Windows フォームと WPF の相互運用性入力アーキテクチャWindows Forms and WPF Interoperability Input Architecture

WPFWPF と Windows フォーム間の相互運用には、両方のテクノロジに適切なキーボード入力処理が必要です。Interoperation between the WPFWPF and Windows Forms requires that both technologies have the appropriate keyboard input processing. このトピックでは、これらのテクノロジでどのようにキーボードおよびメッセージ処理を実装し、ハイブリッド アプリケーションでスムーズな相互運用を可能にする方法について説明します。This topic describes how these technologies implement keyboard and message processing to enable smooth interoperation in hybrid applications.

このトピックは、次の内容で構成されています。This topic contains the following subsections:

  • モードレス フォームとダイアログ ボックスModeless Forms and Dialog Boxes

  • WindowsFormsHost のキーボードとメッセージの処理WindowsFormsHost Keyboard and Message Processing

  • ElementHost のキーボードとメッセージの処理ElementHost Keyboard and Message Processing

モードレス フォームとダイアログ ボックスModeless Forms and Dialog Boxes

WindowsFormsHost 要素に対して EnableWindowsFormsInterop メソッドを呼び出して、WPFWPF ベースのアプリケーションからモードレス フォームまたはダイアログ ボックスを開きます。Call the EnableWindowsFormsInterop method on the WindowsFormsHost element to open a modeless form or dialog box from a WPFWPF-based application.

ElementHost コントロールに対して EnableModelessKeyboardInterop メソッドを呼び出して、Windows フォーム ベースのアプリケーションでモードレス WPFWPF ページを開きます。Call the EnableModelessKeyboardInterop method on the ElementHost control to open a modeless WPFWPF page in a Windows Forms-based application.

WindowsFormsHost のキーボードとメッセージの処理WindowsFormsHost Keyboard and Message Processing

WPFWPF ベースのアプリケーションでホストされている場合、Windows フォームのキーボードとメッセージの処理は以下で構成されます。When hosted by a WPFWPF-based application, Windows Forms keyboard and message processing consists of the following:

  • WindowsFormsHost クラスでは、ComponentDispatcher クラスによって実装されている WPFWPF メッセージ ループからメッセージを取得します。The WindowsFormsHost class acquires messages from the WPFWPF message loop, which is implemented by the ComponentDispatcher class.

  • WindowsFormsHost クラスでは、サロゲート Windows フォーム メッセージ ループを作成し、通常の Windows フォーム キーボード処理が確実に行われるようにします。The WindowsFormsHost class creates a surrogate Windows Forms message loop to ensure that ordinary Windows Forms keyboard processing occurs.

  • WindowsFormsHost クラスでは、IKeyboardInputSink インターフェイスを実装し、WPFWPF を使用してフォーカス管理を調整します。The WindowsFormsHost class implements the IKeyboardInputSink interface to coordinate focus management with WPFWPF.

  • WindowsFormsHost コントロールでは、自身を登録し、メッセージ ループを開始します。The WindowsFormsHost controls register themselves and start their message loops.

以下のセクションでは、プロセスのこれらの部分について詳しく説明します。The following sections describe these parts of the process in more detail.

WPF メッセージ ループからのメッセージの取得Acquiring Messages from the WPF Message Loop

ComponentDispatcher クラスでは、WPFWPF のメッセージ ループ マネージャーを実装します。The ComponentDispatcher class implements the message loop manager for WPFWPF. ComponentDispatcher クラスには、WPFWPF による処理前に外部クライアントでメッセージをフィルター処理できるようになるフックが用意されています。The ComponentDispatcher class provides hooks to enable external clients to filter messages before WPFWPF processes them.

相互運用の実装では ComponentDispatcher.ThreadFilterMessage イベントを処理します。これにより、Windows フォーム コントロールで WPFWPF コントロールの前にメッセージを処理できるようになります。The interoperation implementation handles the ComponentDispatcher.ThreadFilterMessage event, which enables Windows Forms controls to process messages before WPFWPF controls.

サロゲート Windows フォーム メッセージ ループSurrogate Windows Forms Message Loop

既定で、System.Windows.Forms.Application クラスには Windows フォーム アプリケーションのプライマリ メッセージ ループが含まれています。By default, the System.Windows.Forms.Application class contains the primary message loop for Windows Forms applications. 相互運用中、Windows フォーム メッセージ ループによってメッセージは処理されません。During interoperation, the Windows Forms message loop does not process messages. そのため、このロジックを再現する必要があります。Therefore, this logic must be reproduced. ComponentDispatcher.ThreadFilterMessage イベントのハンドラーでは、以下の手順が実行されます。The handler for the ComponentDispatcher.ThreadFilterMessage event performs the following steps:

  1. IMessageFilter インターフェイスを使用してメッセージをフィルター処理します。Filters the message using the IMessageFilter interface.

  2. Control.PreProcessMessage メソッドを呼び出します。Calls the Control.PreProcessMessage method.

  3. 必要に応じて、メッセージを変換してディスパッチします。Translates and dispatches the message, if it is required.

  4. 他のコントロールでメッセージが処理されない場合、メッセージをホスティング コントロールに渡します。Passes the message to the hosting control, if no other controls process the message.

IKeyboardInputSink の実装IKeyboardInputSink Implementation

サロゲート メッセージ ループでは、キーボード管理を処理します。The surrogate message loop handles keyboard management. そのため、IKeyboardInputSink.TabInto メソッドは、WindowsFormsHost クラスでの実装を必要とする唯一の IKeyboardInputSink メンバーです。Therefore, the IKeyboardInputSink.TabInto method is the only IKeyboardInputSink member that requires an implementation in the WindowsFormsHost class.

既定では、HwndHost クラスから、その IKeyboardInputSink.TabInto 実装に対して false が返されます。By default, the HwndHost class returns false for its IKeyboardInputSink.TabInto implementation. これにより、WPFWPF コントロールから Windows フォーム コントロールにタブ移動できなくなります。This prevents tabbing from a WPFWPF control to a Windows Forms control.

IKeyboardInputSink.TabInto メソッドの WindowsFormsHost の実装では、次の手順を実行します。The WindowsFormsHost implementation of the IKeyboardInputSink.TabInto method performs the following steps:

  1. WindowsFormsHost コントロールに含まれ、フォーカスを受け取ることができる最初または最後の Windows フォーム コントロールを見つけます。Finds the first or last Windows Forms control that is contained by the WindowsFormsHost control and that can receive focus. コントロールの選択は、走査情報によって変わります。The control choice depends on traversal information.

  2. コントロールにフォーカスを設定し、true を返します。Sets focus to the control and returns true.

  3. コントロールがフォーカスを受け取ることができない場合は、false を返します。If no control can receive focus, returns false.

WindowsFormsHost の登録WindowsFormsHost Registration

WindowsFormsHost コントロールへのウィンドウ ハンドルが作成されると、WindowsFormsHost コントロールから、メッセージ ループの存在を登録する内部静的メソッドが呼び出されます。When the window handle to a WindowsFormsHost control is created, the WindowsFormsHost control calls an internal static method that registers its presence for the message loop.

登録時に、WindowsFormsHost コントロールによってメッセージ ループが調べられます。During registration, the WindowsFormsHost control examines the message loop. メッセージ ループが開始されていない場合は、ComponentDispatcher.ThreadFilterMessage イベント ハンドラーが作成されます。If the message loop has not been started, the ComponentDispatcher.ThreadFilterMessage event handler is created. メッセージ ループは、ComponentDispatcher.ThreadFilterMessage イベント ハンドラーがアタッチされているときに実行されていると見なされます。The message loop is considered to be running when the ComponentDispatcher.ThreadFilterMessage event handler is attached.

ウィンドウ ハンドルが破棄されると、WindowsFormsHost コントロールが登録から削除されます。When the window handle is destroyed, the WindowsFormsHost control removes itself from registration.

ElementHost のキーボードとメッセージの処理ElementHost Keyboard and Message Processing

Windows フォーム アプリケーションでホストされている場合、WPFWPF キーボードとメッセージの処理は以下で構成されます。When hosted by a Windows Forms application, WPFWPF keyboard and message processing consists of the following:

以下のセクションでは、これらの部分について詳しく説明します。The following sections describe these parts in more detail.

インターフェイスの実装Interface Implementations

Windows フォームでは、キーボード メッセージはフォーカスのあるコントロールのウィンドウ ハンドルにルーティングされます。In Windows Forms, keyboard messages are routed to the window handle of the control that has focus. ElementHost コントロールでは、これらのメッセージはホストされている要素にルーティングされます。In the ElementHost control, these messages are routed to the hosted element. これを実現するために、ElementHost コントロールには HwndSource インスタンスが用意されています。To accomplish this, the ElementHost control provides an HwndSource instance. ElementHost コントロールにフォーカスがある場合、HwndSource インスタンスによってほとんどのキーボード入力がルーティングされ、WPFWPF InputManager クラスで処理できるようになります。If the ElementHost control has focus, the HwndSource instance routes most keyboard input so that it can be processed by the WPFWPF InputManager class.

HwndSource クラスには、IKeyboardInputSink および IKeyboardInputSite インターフェイスが実装されています。The HwndSource class implements the IKeyboardInputSink and IKeyboardInputSite interfaces.

キーボードの相互運用は、ホストされている要素からフォーカスを移動する Tab キーと方向キーの入力を処理する OnNoMoreTabStops メソッドの実装に依存しています。Keyboard interoperation relies on implementing the OnNoMoreTabStops method to handle TAB key and arrow key input that moves focus out of hosted elements.

タブ移動と方向キーTabbing and Arrow Keys

Windows フォーム選択ロジックは、Tab キーと方向キーのナビゲーションを実装するために、IKeyboardInputSink.TabInto および OnNoMoreTabStops メソッドにマップされます。The Windows Forms selection logic is mapped to the IKeyboardInputSink.TabInto and OnNoMoreTabStops methods to implement TAB and arrow key navigation. Select メソッドをオーバーライドすると、このマッピングが行われます。Overriding the Select method accomplishes this mapping.

コマンド キーとダイアログ ボックス キー。Command Keys and Dialog Box Keys

コマンド キーとダイアログ キーを処理する最初の機会を WPFWPF に与えるために、Windows フォーム コマンドの前処理は TranslateAccelerator メソッドに接続されています。To give WPFWPF the first opportunity to process command keys and dialog keys, Windows Forms command preprocessing is connected to the TranslateAccelerator method. Control.ProcessCmdKey メソッドをオーバーライドすると、2 つのテクノロジが接続されます。Overriding the Control.ProcessCmdKey method connects the two technologies.

TranslateAccelerator メソッドを使用すると、ホストされている要素では、WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP などの任意のキー メッセージ (Tab キー、Enter キー、Esc キー、方向キーなどのコマンド キーを含む) を処理できます。With the TranslateAccelerator method, the hosted elements can handle any key message, such as WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP, including command keys, such as TAB, ENTER, ESC, and arrow keys. キー メッセージが処理されない場合は、処理のために Windows フォームの先祖階層が送信されます。If a key message is not handled, it is sent up the Windows Forms ancestor hierarchy for handling.

アクセラレータの処理Accelerator Processing

アクセラレータを正しく処理するには、Windows フォーム アクセラレータ処理を WPFWPF AccessKeyManager クラスに接続する必要があります。To process accelerators correctly, Windows Forms accelerator processing must be connected to the WPFWPF AccessKeyManager class. さらに、すべての WM_CHAR メッセージは、ホストされている要素に正しくルーティングされる必要があります。Additionally, all WM_CHAR messages must be correctly routed to hosted elements.

TranslateChar メソッドの既定の HwndSource 実装からは false が返されるため、WM_CHAR メッセージは次のロジックを使用して処理されます。Because the default HwndSource implementation of the TranslateChar method returns false, WM_CHAR messages are processed using the following logic:

  • すべての WM_CHAR メッセージがホストされる要素に確実に転送されるように、Control.IsInputChar メソッドはオーバーライドされます。The Control.IsInputChar method is overridden to ensure that all WM_CHAR messages are forwarded to hosted elements.

  • Alt キーが押された場合、メッセージは WM_SYSCHAR です。If the ALT key is pressed, the message is WM_SYSCHAR. Windows フォームでは、IsInputChar メソッドを通じてこのメッセージが前処理されません。Windows Forms does not preprocess this message through the IsInputChar method. そのため、ProcessMnemonic メソッドは、登録されたアクセラレータの WPFWPF AccessKeyManager のクエリを実行するためにオーバーライドされます。Therefore, the ProcessMnemonic method is overridden to query the WPFWPF AccessKeyManager for a registered accelerator. 登録されているアクセラレータが見つかった場合、AccessKeyManager によってそれが処理されます。If a registered accelerator is found, AccessKeyManager processes it.

  • Alt キーが押されていない場合、WPFWPF InputManager クラスによって未処理の入力が処理されます。If the ALT key is not pressed, the WPFWPF InputManager class processes the unhandled input. 入力がアクセラレータである場合、AccessKeyManager によって処理されます。If the input is an accelerator, the AccessKeyManager processes it. PostProcessInput イベントは、処理されなかった WM_CHAR メッセージに対して処理されます。The PostProcessInput event is handled for WM_CHAR messages that were not processed.

ユーザーが Alt キーを押すと、フォーム全体にアクセラレータの視覚的な合図が表示されます。When the user presses the ALT key, accelerator visual cues are shown on the whole form. この動作をサポートするために、アクティブなフォームのすべての ElementHost コントロールは、フォーカスのあるコントロールに関係なく、WM_SYSKEYDOWN メッセージを受け取ります。To support this behavior, all ElementHost controls on the active form receive WM_SYSKEYDOWN messages, regardless of which control has focus.

メッセージはアクティブ フォームの ElementHost コントロールにのみ送信されます。Messages are sent only to ElementHost controls in the active form.

関連項目See also