Udostępnij za pośrednictwem


Architektura wejściowa interoperacyjności formularzy systemu Windows 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:

  • Niemodalne formularze i okna dialogowe

  • WindowsFormsHost Klawiatura i przetwarzanie komunikatów

  • ElementHost Klawiatura i przetwarzanie komunikatów

Formularze i okna dialogowe bez trybu

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

Wywołaj metodę EnableModelessKeyboardInterop na kontrolce ElementHost, aby otworzyć bezmodalną stronę WPF w aplikacji opartej na Windows Forms.

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:

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ółpracy obsługuje zdarzenie ComponentDispatcher.ThreadFilterMessage, które umożliwia kontrolkom Windows Forms przetwarzanie komunikatów przed kontrolkami WPF.

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

Domyślnie klasa System.Windows.Forms.Application 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ługująca zdarzenie 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ą. W związku z tym metoda IKeyboardInputSink.TabInto jest jedynym elementem członkowskim IKeyboardInputSink, który wymaga implementacji w klasie WindowsFormsHost.

Domyślnie klasa HwndHost zwraca false dla implementacji IKeyboardInputSink.TabInto. Zapobiega to tabulacji z kontrolki WPF do kontrolki Windows Forms.

Implementacja WindowsFormsHost metody IKeyboardInputSink.TabInto wykonuje następujące czynności:

  1. Znajduje pierwszą lub ostatnią kontrolkę Windows Forms, która jest zawarta w kontrolce WindowsFormsHost i może uzyskać focus. Wybór sterowania zależy od informacji dotyczących przemierzania.

  2. Ustawia fokus na kontrolkę i zwraca true.

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

Rejestracja elementu WindowsFormsHost

Po utworzeniu uchwytu okna do kontrolki WindowsFormsHost 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 procedura obsługi zdarzeń ComponentDispatcher.ThreadFilterMessage. Pętla komunikatów jest uważana za uruchomioną po dołączeniu programu obsługi zdarzeń ComponentDispatcher.ThreadFilterMessage.

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 element sterujący ElementHost zapewnia instancję HwndSource. Jeśli kontrolka ElementHost ma fokus, to wystąpienie HwndSource kieruje większość danych wejściowych z klawiatury, aby klasa InputManager WPF mogła je przetworzyć.

Klasa HwndSource implementuje interfejsy IKeyboardInputSink i IKeyboardInputSite.

Interoperacyjność klawiatury polega na zaimplementowaniu metody OnNoMoreTabStops do obsługi klawisza TAB i klawiszy strzałek, które przenoszą fokus poza hostowane elementy.

Tabulatory i klawisze strzałek

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

Klawisze poleceń i okna dialogowego

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

Za pomocą metody TranslateAccelerator hostowane elementy mogą obsługiwać dowolny komunikat klawisza, taki jak WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN lub WM_SYSKEYUP, w tym klawisze 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 poprawnie przetwarzać akceleratory, przetwarzanie akceleratorów Windows Forms musi być połączone z klasą AccessKeyManager WPF. Ponadto wszystkie komunikaty WM_CHAR muszą być prawidłowo kierowane do elementów hostowanych.

Ponieważ domyślna implementacja HwndSource metody TranslateChar zwraca false, komunikaty WM_CHAR 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 elementów hostowanych.

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

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

Gdy użytkownik naciśnie ALT, wskazówki wizualne akceleratora są wyświetlane w całym formularzu. Aby obsłużyć to zachowanie, wszystkie kontrolki oznaczone jako ElementHost w aktywnym formularzu odbierają komunikaty WM_SYSKEYDOWN, niezależnie od tego, która kontrolka jest w danym momencie w centrum uwagi.

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

Zobacz też