Partager via


Architecture d’entrée d’interopérabilité Windows Forms et WPF

L’interopérabilité entre WPF et Windows Forms nécessite que les deux technologies disposent du traitement d’entrée du clavier approprié. Cette rubrique décrit comment ces technologies implémentent le traitement du clavier et des messages pour permettre l’interopérabilité fluide dans les applications hybrides.

Cette rubrique contient les sous-sections suivantes :

  • Formulaires et boîtes de dialogue sans mode

  • Clavier WindowsFormsHost et traitement des messages

  • Traitement du clavier et des messages ElementHost

Formulaires et boîtes de dialogue sans mode

Appelez la méthode EnableWindowsFormsInterop de l'élément WindowsFormsHost pour ouvrir un formulaire ou une boîte de dialogue modèle à partir d’une application WPF.

Appelez la méthode EnableModelessKeyboardInterop sur le contrôle utilisateur ElementHost pour présenter une page WPF sans fenêtre modale dans une application Windows Forms.

Clavier WindowsFormsHost et traitement des messages

Lorsqu’il est hébergé par une application WPF, le clavier Windows Forms et le traitement des messages se composent des éléments suivants :

  • La WindowsFormsHost classe acquiert des messages à partir de la boucle de message WPF, qui est implémentée par la ComponentDispatcher classe.

  • La classe WindowsFormsHost crée une boucle de messages substitut pour Windows Forms afin de garantir que le traitement standard du clavier Windows Forms s'effectue correctement.

  • La classe WindowsFormsHost implémente l’interface IKeyboardInputSink pour coordonner la gestion du focus avec WPF.

  • Les WindowsFormsHost contrôles s’enregistrent eux-mêmes et démarrent leurs boucles de message.

Les sections suivantes décrivent plus en détail ces parties du processus.

Acquisition de messages à partir de la boucle de message WPF

La ComponentDispatcher classe implémente le gestionnaire de boucles de message pour WPF. La ComponentDispatcher classe fournit des hooks pour permettre aux clients externes de filtrer les messages avant que WPF les traite.

L’implémentation d’interopérabilité gère l’événement ComponentDispatcher.ThreadFilterMessage , ce qui permet aux contrôles Windows Forms de traiter les messages avant les contrôles WPF.

Boucle de message Windows Forms remplaçante

Par défaut, la System.Windows.Forms.Application classe contient la boucle de message principale pour les applications Windows Forms. Pendant l’interopérabilité, la boucle de message Windows Forms ne traite pas les messages. Par conséquent, cette logique doit être reproduite. Le gestionnaire de l’événement ComponentDispatcher.ThreadFilterMessage effectue les étapes suivantes :

  1. Filtre le message à l’aide de l’interface IMessageFilter .

  2. Appelle la Control.PreProcessMessage méthode.

  3. Traduit et distribue le message, s’il est nécessaire.

  4. Transmet le message au contrôle d’hébergement, si aucun autre contrôle ne traite le message.

Implémentation de "IKeyboardInputSink"

La boucle de message de substitution gère la gestion du clavier. Par conséquent, la IKeyboardInputSink.TabInto méthode est le seul IKeyboardInputSink membre qui nécessite une implémentation dans la WindowsFormsHost classe.

Par défaut, la HwndHost classe retourne false pour son IKeyboardInputSink.TabInto implémentation. Cela empêche le tabulation d’un contrôle WPF vers un contrôle Windows Forms.

L’implémentation WindowsFormsHost de la IKeyboardInputSink.TabInto méthode effectue les étapes suivantes :

  1. Recherche le premier ou le 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 traversée.

  2. Définit le focus du contrôle et retourne true.

  3. Si aucun contrôle ne peut recevoir le focus, retourne false.

Enregistrement WindowsFormsHost

Lorsque le handle de fenêtre d'un contrôle WindowsFormsHost est créé, le contrôle WindowsFormsHost appelle une méthode statique interne pour inscrire sa présence dans la boucle de messages.

Pendant l’inscription, le WindowsFormsHost contrôle examine la file de messages. Si la boucle de message n’a pas été démarrée, le ComponentDispatcher.ThreadFilterMessage gestionnaire d’événements est créé. La boucle de message est considérée comme s’exécutant lorsque le ComponentDispatcher.ThreadFilterMessage gestionnaire d’événements est attaché.

Lorsque le handle de fenêtre est détruit, le WindowsFormsHost contrôle se supprime de l’inscription.

Traitement du clavier et des messages ElementHost

Lorsqu’il est hébergé par une application Windows Forms, le clavier WPF et le traitement des messages se composent des éléments suivants :

Les sections suivantes décrivent ces parties plus en détail.

Implémentations d’interface

Dans Windows Forms, les messages clavier sont routés vers le gestionnaire de fenêtre du contrôle qui a le focus. Dans le ElementHost contrôle, ces messages sont routés vers l’élément hébergé. Pour ce faire, le ElementHost contrôle fournit une HwndSource instance. Si le contrôle ElementHost est focalisé, l’instance HwndSource achemine la plupart des entrées clavier pour qu'elles soient traitées par la classe WPF InputManager.

La HwndSource classe implémente les interfaces IKeyboardInputSink et IKeyboardInputSite.

L’interopérabilité du clavier s’appuie sur l’implémentation de la méthode pour gérer la touche TAB et l’entrée de touche de direction qui déplacent le OnNoMoreTabStops focus hors 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 par les touches de tabulation et flèches. La redéfinition de la méthode Select permet de réaliser ce mappage.

Touches de commande et touches de boîte de dialogue

Pour donner à WPF la première occasion de traiter les clés de commande et les clés de boîte de dialogue, le prétraitement de commande Windows Forms est connecté à la TranslateAccelerator méthode. Le remplacement de la méthode Control.ProcessCmdKey connecte les deux technologies.

Avec la TranslateAccelerator méthode, les éléments hébergés peuvent gérer n’importe quel message clé, tel que WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN ou WM_SYSKEYUP, y compris les touches de commande, telles que TAB, ENTRÉE, ÉCHAP et touches de direction. Si un message clé n’est pas géré, il est envoyé à la hiérarchie ancêtre Windows Forms pour la gestion.

Traitement de l’accélérateur

Pour traiter correctement les accélérateurs, le traitement de l’accélérateur Windows Forms doit être connecté à la classe WPF AccessKeyManager . En outre, tous les messages WM_CHAR doivent être correctement routés vers les éléments hébergés.

Étant donné que l’implémentation par défaut HwndSource de la TranslateChar méthode retourne false, WM_CHAR messages sont traités à l’aide de la logique suivante :

  • La méthode Control.IsInputChar est redéfinie afin de garantir que tous les messages WM_CHAR sont transférés aux éléments hébergés.

  • Si la touche ALT est enfoncée, le message est WM_SYSCHAR. Windows Forms ne prétraite pas ce message par le biais de la IsInputChar méthode. Par conséquent, la méthode ProcessMnemonic est substituée pour interroger le WPF AccessKeyManager pour un accélérateur inscrit. Si un accélérateur inscrit est trouvé, AccessKeyManager le traite.

  • Si la touche ALT n’est pas enfoncée, la classe WPF InputManager traite l’entrée non gérée. Si l’entrée est un accélérateur, le AccessKeyManager le traite. L’événement PostProcessInput est géré pour WM_CHAR messages qui n’ont pas été traités.

Lorsque l’utilisateur appuie sur la touche ALT, les indications visuelles de l’accélérateur s’affichent sur l’ensemble du formulaire. Pour prendre en charge ce comportement, tous les ElementHost contrôles du formulaire actif reçoivent les messages WM_SYSKEYDOWN, quel que soit le contrôle qui a le focus.

Les messages sont envoyés uniquement aux ElementHost contrôles du formulaire actif.

Voir aussi