Struktura wejścia ze zdolnością do współpracy Windows Forms i WPF

Współdziałanie między WPF i Windows Forms wymaga, aby obie technologie miały odpowiednie przetwarzanie danych wejściowych klawiatury. W tym temacie opisano, jak te technologie implementują przetwarzanie klawiatury i komunikatów w celu zapewnienia bezproblemowej współpracy w aplikacjach hybrydowych.

Ten temat zawiera następujące podsekcje:

  • Trybowe formularze i okna dialogowe

  • WindowsFormsHost Klawiatura i przetwarzanie komunikatów

  • ElementHost Klawiatura i przetwarzanie komunikatów

Trybowe formularze i okna dialogowe

Wywołaj metodę EnableWindowsFormsInterop elementu WindowsFormsHost , aby otworzyć formularz lub okno dialogowe bez moderowania z aplikacji opartej na WPF.

Wywołaj metodę EnableModelessKeyboardInterop na kontrolce ElementHost , aby otworzyć bez moderową stronę WPF w aplikacji opartej na formularzach systemu Windows.

WindowsFormsHost Klawiatura i przetwarzanie komunikatów

W przypadku hostowania przez aplikację opartą na WPF przetwarzanie klawiatury i komunikatów windows Forms składa się z następujących elementów:

  • Klasa WindowsFormsHost uzyskuje komunikaty z pętli komunikatów WPF, która jest implementowana przez klasę ComponentDispatcher .

  • Klasa WindowsFormsHost tworzy zastępczą pętlę komunikatów formularzy systemu Windows w celu zapewnienia, że odbywa się zwykłe przetwarzanie klawiatury windows Forms.

  • Klasa WindowsFormsHost implementuje IKeyboardInputSink interfejs do koordynowania zarządzania fokusem za pomocą WPF.

  • Kontrolki WindowsFormsHost rejestrują się i uruchamiają pętle komunikatów.

W poniższych sekcjach opisano bardziej szczegółowo te części procesu.

Uzyskiwanie komunikatów z pętli komunikatów WPF

Klasa ComponentDispatcher implementuje menedżera pętli komunikatów dla WPF. Klasa ComponentDispatcher udostępnia haki, aby umożliwić klientom zewnętrznym filtrowanie komunikatów przed ich przetwarzaniem przez WPF.

Implementacja współdziałania obsługuje ComponentDispatcher.ThreadFilterMessage zdarzenie, co umożliwia kontrolkom Windows Forms przetwarzanie komunikatów przed kontrolkami WPF.

Zastępcza pętla komunikatów formularzy systemu Windows

Domyślnie System.Windows.Forms.Application klasa zawiera podstawową pętlę komunikatów dla aplikacji Windows Forms. Podczas współdziałania pętla komunikatów formularzy systemu Windows nie przetwarza komunikatów. W związku z tym należy odtworzyć tę logikę. Procedura obsługi zdarzenia ComponentDispatcher.ThreadFilterMessage wykonuje następujące czynności:

  1. Filtruje komunikat przy użyciu interfejsu IMessageFilter .

  2. Wywołuje metodę Control.PreProcessMessage .

  3. Tłumaczy i wysyła komunikat, jeśli jest to wymagane.

  4. Przekazuje komunikat do kontrolki hostingu, jeśli żadne inne kontrolki nie przetwarzają komunikatu.

Implementacja IKeyboardInputSink

Pętla komunikatów zastępczych obsługuje zarządzanie klawiaturą. IKeyboardInputSink.TabInto W związku z tym metoda jest jedynym IKeyboardInputSink elementem członkowskim, który wymaga implementacji WindowsFormsHost w klasie .

Domyślnie HwndHost klasa zwraca false swoją implementację IKeyboardInputSink.TabInto . Zapobiega to tabulacji z kontrolki WPF do kontrolki Formularze systemu Windows.

Implementacja WindowsFormsHostIKeyboardInputSink.TabInto metody wykonuje następujące kroki:

  1. Znajduje pierwszą lub ostatnią kontrolkę Formularzy systemu Windows, która jest zawarta przez kontrolkę WindowsFormsHost i może uzyskać fokus. Wybór kontrolki zależy od informacji przechodzenia.

  2. Ustawia fokus na kontrolkę i zwraca wartość true.

  3. Jeśli żadna kontrolka nie może odbierać fokusu, zwraca wartość false.

Rejestracja elementu WindowsFormsHost

Po utworzeniu uchwytu okna do WindowsFormsHost kontrolki kontrolka WindowsFormsHost wywołuje wewnętrzną metodę statyczną, która rejestruje swoją obecność w pętli komunikatów.

Podczas rejestracji kontrolka WindowsFormsHost sprawdza pętlę komunikatu. Jeśli pętla komunikatów nie została uruchomiona, zostanie utworzona ComponentDispatcher.ThreadFilterMessage procedura obsługi zdarzeń. Pętla komunikatów jest uważana za uruchomioną ComponentDispatcher.ThreadFilterMessage , gdy program obsługi zdarzeń jest dołączony.

Gdy uchwyt okna zostanie zniszczony, kontrolka WindowsFormsHost usunie się z rejestracji.

ElementHost Klawiatura i przetwarzanie komunikatów

W przypadku hostowania przez aplikację Windows Forms klawiatura WPF i przetwarzanie komunikatów składa się z następujących elementów:

W poniższych sekcjach opisano te części bardziej szczegółowo.

Implementacje interfejsu

W formularzach Systemu Windows komunikaty klawiaturowe są kierowane do uchwytu okna kontrolki, która ma fokus. W kontrolce ElementHost te komunikaty są kierowane do elementu hostowanego. W tym celu kontrolka ElementHost udostępnia HwndSource wystąpienie. Jeśli kontrolka ElementHost ma fokus, HwndSource wystąpienie kieruje większość danych wejściowych klawiatury, aby można je było przetworzyć przez klasę WPF InputManager .

Klasa HwndSource implementuje IKeyboardInputSink interfejsy i IKeyboardInputSite .

Współdziałanie klawiatury polega na zaimplementowaniu OnNoMoreTabStops metody do obsługi klawisza TAB i klawisza strzałki, która przenosi fokus poza hostowane elementy.

Tabulatory i klawisze strzałek

Logika wyboru formularzy systemu Windows jest mapowana na metody i OnNoMoreTabStops w IKeyboardInputSink.TabInto celu zaimplementowania nawigacji klawiszem TAB i klawiszem strzałki. Select Zastąpienie metody powoduje wykonanie tego mapowania.

Klawisze poleceń i klawisze okna dialogowego

Aby dać WPF pierwszą możliwość przetwarzania kluczy poleceń i kluczy okien dialogowych, wstępne przetwarzanie poleceń windows Forms jest połączone z TranslateAccelerator metodą . Control.ProcessCmdKey Zastąpienie metody łączy dwie technologie.

Za pomocą TranslateAccelerator metody hostowane elementy mogą obsługiwać dowolny komunikat klucza, taki jak WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN lub WM_SYSKEYUP, w tym klucze poleceń, takie jak TAB, ENTER, ESC i klawisze strzałek. Jeśli komunikat klucza nie jest obsługiwany, jest wysyłany do hierarchii obiektów nadrzędnych windows Forms do obsługi.

Przetwarzanie akceleratora

Aby prawidłowo przetwarzać akceleratory, przetwarzanie akceleratora formularzy systemu Windows musi być połączone z klasą WPF AccessKeyManager . Ponadto wszystkie komunikaty WM_CHAR muszą być prawidłowo kierowane do elementów hostowanych.

Ponieważ domyślna HwndSource implementacja TranslateChar metody zwraca falsewartość , WM_CHAR komunikaty są przetwarzane przy użyciu następującej logiki:

  • Metoda Control.IsInputChar jest zastępowana, aby upewnić się, że wszystkie komunikaty WM_CHAR są przekazywane do hostowanych elementów.

  • Jeśli klawisz ALT jest naciśnięty, komunikat jest WM_SYSCHAR. Formularze systemu Windows nie przetwarzają wstępnie tego komunikatu IsInputChar za pośrednictwem metody . W związku z tym ProcessMnemonic metoda jest zastępowana w celu wykonywania zapytań dotyczących WPF AccessKeyManager dla zarejestrowanego akceleratora. Jeśli znaleziono zarejestrowany akcelerator, AccessKeyManager przetwarza go.

  • Jeśli klawisz ALT nie jest naciśnięty, klasa WPF InputManager przetwarza nieobsługiwane dane wejściowe. Jeśli dane wejściowe są akceleratorem, AccessKeyManager przetwarza je. Zdarzenie PostProcessInput jest obsługiwane dla komunikatów WM_CHAR, które nie zostały przetworzone.

Gdy użytkownik naciśnie klawisz ALT, wskazówki wizualne akceleratora są wyświetlane w całym formularzu. Aby obsługiwać to zachowanie, wszystkie ElementHost kontrolki w aktywnym formularzu odbierają komunikaty WM_SYSKEYDOWN, niezależnie od tego, która kontrolka ma fokus.

Komunikaty są wysyłane tylko do ElementHost kontrolek w aktywnym formularzu.

Zobacz też