本文內容
非強制回應表單和對話方塊
WindowsFormsHost 鍵盤和訊息處理
ElementHost 鍵盤和訊息處理
另請參閱
WPF 與 Windows Forms 之間的互操作需要這兩種技術都有適當的鍵盤輸入處理。 本主題描述這些技術如何實作鍵盤和訊息處理,以在混合式應用程式中啟用平滑的互操作。
本主題包含下列子章節:
非強制回應表單和對話方塊
WindowsFormsHost 鍵盤和訊息處理
ElementHost 鍵盤和訊息處理
在 EnableWindowsFormsInterop 元素上呼叫 WindowsFormsHost 方法,以從 WPF 型應用程式開啟非強制回應表單或對話方塊。
在 EnableModelessKeyboardInterop 控制項上呼叫 ElementHost 方法,以在 Windows Forms 型應用程式中開啟非強制回應 WPF 頁面。
以 WPF 型應用程式裝載時,Windows Forms 鍵盤和訊息處理包含下列項目:
下列各節將更詳細說明流程的這些部分。
ComponentDispatcher 類別會實作 WPF 的訊息迴圈管理員。
ComponentDispatcher 類別提供勾點,讓外部用戶端在 WPF 處理訊息之前篩選訊息。
互操作實作會處理 ComponentDispatcher.ThreadFilterMessage 事件,這可讓 Windows Forms 控制項在 WPF 控制項之前處理訊息。
根據預設,System.Windows.Forms.Application 類別包含 Windows Forms 應用程式的主要訊息迴圈。 在互操作期間,Windows Forms 訊息迴圈不會處理訊息。 因此,必須重現此邏輯。
ComponentDispatcher.ThreadFilterMessage 事件的處理程式會執行下列步驟:
使用 IMessageFilter 介面篩選訊息。
呼叫 Control.PreProcessMessage 方法。
如果需要,翻譯並分派訊息。
如果沒有其他控制項處理訊息,則將訊息傳遞至裝載控制項。
Surrogate 訊息迴圈會處理鍵盤管理。 因此,IKeyboardInputSink.TabInto 方法是唯一需要 IKeyboardInputSink 類別中實作的 WindowsFormsHost 成員。
根據預設,HwndHost 類別會傳回其 false
實作的 IKeyboardInputSink.TabInto 。 這可防止從 WPF 控制項移至 Windows Forms 控制項的定位處理。
WindowsFormsHost 方法的 IKeyboardInputSink.TabInto 實作會執行下列步驟:
尋找 WindowsFormsHost 控制項所包含的第一個或最後一個 Windows Forms 控制項,而且可以接收焦點。 控制項選擇取決於周遊資訊。
將焦點設定為控制項,並傳回 true
。
如果沒有控制項可以接收焦點,則會傳回 false
。
建立至 WindowsFormsHost 控制項的視窗控制代碼時,WindowsFormsHost 控制項會呼叫內部靜態方法,以註冊其訊息迴圈的存在。
在註冊期間,WindowsFormsHost 控制項會檢查訊息迴圈。 如果訊息迴圈尚未啟動,則會建立 ComponentDispatcher.ThreadFilterMessage 事件處理程式。 附加 ComponentDispatcher.ThreadFilterMessage 事件處理程式時,訊息迴圈會被視為正在執行。
當視窗控制代碼終結時,WindowsFormsHost 控制項會從註冊中移除其本身。
由 Windows Forms 應用程式裝載時,WPF 鍵盤和訊息處理包含下列項目:
下列各節會更詳細地說明這些部分。
在 Windows Forms 中,鍵盤訊息會路由傳送至具有焦點之控制項的視窗控制代碼。 在 ElementHost 控制項中,這些訊息會路由傳送至裝載元素。 若要達成此目的,ElementHost 控制項會提供 HwndSource 實例。 如果 ElementHost 控制項有焦點,HwndSource 實例會路由傳送大部分的鍵盤輸入,以便 WPF InputManager 類別處理它。
HwndSource 類別會實作 IKeyboardInputSink 和 IKeyboardInputSite 介面。
鍵盤互操作依賴實作 OnNoMoreTabStops 方法來處理 TAB 鍵和方向鍵輸入,以將焦點移出裝載元素。
Windows Forms 選取邏輯會對應至 IKeyboardInputSink.TabInto 及 OnNoMoreTabStops 方法來實作 TAB 和方向鍵瀏覽。 覆寫 Select 方法會完成此對應。
為了讓 WPF 第一次有機會處理命令索引鍵和對話方塊索引鍵,Windows Forms 命令前置處理會連線到 TranslateAccelerator 方法。 覆寫 Control.ProcessCmdKey 方法會連接這兩種技術。
使用 TranslateAccelerator 方法,裝載元素可以處理任何索引鍵訊息,例如 WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN 或WM_SYSKEYUP,包括 TAB、ENTER、ESC 和方向鍵。 如果未處理索引鍵訊息,則會向上傳送至 Windows Forms 上階階層進行處理。
若要正確處理加速器,Windows Forms 加速器處理必須連線到 WPF AccessKeyManager 類別。 此外,所有 WM_CHAR 訊息都必須正確路由傳送至裝載元素。
由於 HwndSource 方法的預設 TranslateChar 實作會傳回 false
,因此會使用下列邏輯來處理 WM_CHAR 訊息:
當使用者按下 ALT 鍵時,整個表單上會顯示加速器視覺效果提示。 為了支援此行為,不論哪個控制項具有焦點,使用中表單上的所有 ElementHost 控制項都會接收 WM_SYSKEYDOWN 訊息。
訊息只會傳送至使用中表單上的 ElementHost 控制項。