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:
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 windows Forms w celu zapewnienia, że ma miejsce zwykłe przetwarzanie klawiatury windows Forms.
Klasa WindowsFormsHost implementuje interfejs IKeyboardInputSink w celu koordynowania zarządzania fokusem w środowisku 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ół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:
Filtruje komunikat przy użyciu interfejsu IMessageFilter.
Wywołuje metodę Control.PreProcessMessage.
Tłumaczy i wysyła komunikat, jeśli jest to wymagane.
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:
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.
Ustawia fokus na kontrolkę i zwraca
true
.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:
implementacje interfejsu HwndSource, IKeyboardInputSinki IKeyboardInputSite.
Klawisz Tab oraz klawisze strzałek.
Klucze poleceń i klucze okna dialogowego.
Przetwarzanie akceleratora Windows Forms.
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ż
.NET Desktop feedback