Architecture d'entrée pour l'interopérabilité entre Windows Forms et WPF
Mise à jour : novembre 2007
L'interopérabilité entre WPF et Windows Forms requiert que les deux technologies disposent du traitement d'entrée au clavier approprié. Cette rubrique décrit comment ces technologies implémentent le traitement de message et d'entrée au clavier pour permettre l'interopérabilité régulière dans des applications hybrides.
Cette rubrique contient les sous-sections suivantes :
Formulaires et boîtes de dialogue non modaux
Clavier WindowsFormsHost et traitement des messages
Clavier ElementHost et traitement des messages
Formulaires et boîtes de dialogue non modaux
Appelez la méthode EnableWindowsFormsInterop sur l'élément WindowsFormsHost pour ouvrir une boîte de dialogue ou un formulaire non modal à partir d'une application WPF.
Appelez la méthode EnableModelessKeyboardInterop sur le contrôle ElementHost pour ouvrir une page WPF non modale dans une application Windows Forms.
Clavier WindowsFormsHost et traitement des messages
Lorsqu'il est hébergé par une application WPF, clavier Windows Forms et le traitement des messages est composé des éléments suivants :
La classe WindowsFormsHost acquiert des messages à partir de la boucle de message WPF, implémentée par la classe ComponentDispatcher.
La classe WindowsFormsHost crée une boucle de message Windows Forms de remplacement pour s'assurer que le traitement de clavier Windows Forms ordinaire se produit.
La classe WindowsFormsHost implémente l'interface IKeyboardInputSink pour coordonner la gestion du focus avec WPF.
Les contrôles WindowsFormsHost s'inscrivent et démarrent leurs boucles de messages.
Les sections suivantes décrivent ces parties du processus de façon approfondie.
Acquérir des messages de la boucle de message Windows Presentation Foundation
La classe ComponentDispatcher implémente le gestionnaire de boucle de message pour WPF. La classe ComponentDispatcher fournit des raccordements pour permettre aux clients externes de filtrer des messages avant que WPF les traite.
L'implémentation d'interopérabilité gère l'événement ComponentDispatcher.ThreadFilterMessage, qui permet aux contrôles Windows Forms de traiter des messages avant les contrôles WPF.
Boucle de message Windows Forms de remplacement
Par défaut, la classe System.Windows.Forms.Application contient la boucle de message principale pour les applications Windows Forms. Pendant l'interopérabilité, la boucle de message Windows Forms ne traite pas de messages. Par conséquent, cette logique doit être reproduite. Le gestionnaire pour l'événement ComponentDispatcher.ThreadFilterMessage exécute les étapes suivantes :
Filtre le message à l'aide de l'interface IMessageFilter.
Appelle la méthode Control.PreProcessMessage.
Traduit et distribue le message, si nécessaire.
Passe le message au contrôle d'hébergement, si aucun autre contrôle ne traite le message.
Implémentation IKeyboardInputSink
La boucle de message de remplacement gère la gestion du clavier. Par conséquent, la méthode IKeyboardInputSink.TabInto est le seul membre IKeyboardInputSink qui nécessite une implémentation dans la classe WindowsFormsHost.
Par défaut, la classe HwndHost retourne false pour son implémentation IKeyboardInputSink.TabInto. Cela empêche la tabulation à partir d'un contrôle WPF vers un contrôle Windows Forms.
L'implémentation WindowsFormsHost de la méthode IKeyboardInputSink.TabInto exécute les étapes suivantes :
Recherche le premier ou dernier contrôle Windows Forms contenu par le contrôle WindowsFormsHost et qui peut recevoir le focus. Le choix du contrôle dépend des informations de parcours.
Définit le focus sur le contrôle et retourne true.
Si aucun contrôle ne peut recevoir le focus, retourne false.
Inscription WindowsFormsHost
Lorsque le handle de fenêtre sur un contrôle WindowsFormsHost est créé, le contrôle WindowsFormsHost appelle une méthode statique interne qui enregistre sa présence pour la boucle de message.
Pendant l'inscription, le contrôle WindowsFormsHost examine la boucle de message. Si la boucle de message n'a pas été démarrée, le gestionnaire d'événements ComponentDispatcher.ThreadFilterMessage est créé. La boucle de message est considérée être exécutée lorsque le gestionnaire d'événements ComponentDispatcher.ThreadFilterMessage est attaché.
Lorsque le handle de fenêtre est détruit, le contrôle WindowsFormsHost s'élimine lui-même de l'inscription.
Clavier ElementHost et traitement des messages
Lorsqu'il est hébergé par une application Windows Forms, clavier WPF et le traitement des messages est composé des éléments suivants :
HwndSource, IKeyboardInputSink et IKeyboardInputSite des implémentations d'interface.
Tabulation et touches de direction.
Touches de commande et touches de boîte de dialogue.
Traitement d'accélérateur Windows Forms.
Les sections suivantes décrivent ces parties de façon approfondie.
Implémentations d'interface
Dans Windows Forms, les messages du clavier sont routés vers le handle de la fenêtre du contrôle qui a le focus. Dans le contrôle ElementHost, ces messages sont routés vers l'élément hébergé. Pour accomplir ceci, le contrôle ElementHost fournit une instance HwndSource. Si le contrôle ElementHost a le focus, l'instance HwndSource route la plupart des entrées au clavier afin qu'elles puissent être traitées par la classe WPFInputManager.
La classe HwndSource implémente les interfaces IKeyboardInputSink et IKeyboardInputSite.
L'interopérabilité de clavier s'appuie sur l'implémentation de la méthode OnNoMoreTabStops pour gérer la touche TAB et l'entrée de la touche de direction qui déplace le focus en dehors des éléments hébergés.
Tabulation et touches de direction
La logique de sélection Windows Forms est mappée aux méthodes IKeyboardInputSink.TabInto et OnNoMoreTabStops pour implémenter la navigation avec les touches de direction et la navigation TAB. La substitution de la méthode Select réalise ce mappage.
Touches de commande et touches de boîte de dialogue
Pour donner à WPF la première possibilité de traiter les touches de commande et les touches de boîte de dialogue, le prétraitement de commande Windows Forms est connecté à la méthode TranslateAccelerator. La substitution de la méthode Control.ProcessCmdKey connecte les deux technologies.
Avec la méthode TranslateAccelerator, les éléments hébergés peuvent gérer tout message clé, tel que WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN ou WM_SYSKEYUP, y compris les touches de commande telles que TABULATION, ENTRÉE, ÉCHAP et les touches de direction. Si un message clé n'est pas géré, il est renvoyé en haut de la hiérarchie ancêtre Windows Forms à des fins de gestion.
Traitement d'accélérateur
Pour traiter des accélérateurs correctement, le traitement d'accélérateur Windows Forms doit être connecté à la classe WPFAccessKeyManager. En outre, tous les messages WM_CHAR doivent être routés correctement aux éléments hébergés.
Parce que l'implémentation HwndSource par défaut de la méthode TranslateChar retourne false, les messages WM_CHAR sont traités à l'aide de la logique suivante :
La méthode Control.IsInputChar est substituée pour garantir que tous les messages WM_CHAR sont envoyés aux éléments hébergés.
Si l'utilisateur appuie sur la touche ALT, le message est WM_SYSCHAR. Windows Forms ne prétraite pas ce message via la méthode IsInputChar. Par conséquent, la méthode ProcessMnemonic est substituée pour interroger WPFAccessKeyManager pour obtenir un accélérateur enregistré. Si un accélérateur enregistré est trouvé, AccessKeyManager le traite.
Si l'utilisateur n'appuie pas sur la touche ALT, la classe WPFInputManager traite l'entrée non gérée. Si l'entrée est un accélérateur, AccessKeyManager le traite. L'événement PostProcessInput est géré pour les messages WM_CHAR qui n'ont pas été traités.
Lorsque l'utilisateur appuie sur la touche ALT, des aides visuelles de l'accélérateur s'affichent sur l'intégralité du formulaire. Pour prendre en charge ce comportement, tous les contrôles ElementHost sur le formulaire actif reçoivent des messages WM_SYSKEYDOWN, quel que soit le contrôle qui a le focus.
Les messages sont envoyés uniquement aux contrôles ElementHost dans le formulaire actif.
Voir aussi
Concepts
Vue d'ensemble de l'interopérabilité WPF et Win32