DirectManipulation を使用した入力の処理
このセクションでは、直接操作スレッド モデルの概要、 直接操作 によってウィンドウ メッセージを処理する方法、および入力が出力モーションにマップされるときにビューポートの状態がどのように変化するかを説明します。
直接操作 では、2 つのスレッドを使用して非同期操作を調整します。
UI スレッド - 入力に関連付けられている HWND を所有するスレッド。 このスレッドは、 直接操作の初期化を所有しています。 マウスとキーボードの入力処理は、UI スレッドでも行われます。
デリゲート スレッド - 直接操作によって作成および所有されるスレッド。 タッチ入力処理は、デリゲート スレッドで行われます。
入力フロー
UI スレッドでヒット テストが行われる一般的な構成では、ウィンドウ メッセージは 直接操作 によって次の順序で処理されます。
保存ビューポートの場合:
- 一連のウィンドウ メッセージがデリゲート スレッドに到達します。
- WM_POINTERDOWN メッセージと DM_POINTERHITTEST メッセージは、委任スレッドによって独立ヒット テスト (IHT) スレッドに送信されます。
- IHT スレッドから SetContact が呼び出された場合、RegisterHitTestTarget が呼び出されたときのDIRECTMANIPULATION_HITTEST_TYPEの値に応じて、メッセージがデリゲート スレッドによって UI スレッドに送信されることがあります。
- SetContact が IHT スレッドから呼び出されない場合、メッセージは常にデリゲート スレッドによって UI スレッドに送信されます。
- クライアントは、UI スレッドから SetContact を呼び出して、 直接操作 が操作を検出できるようにします。
- 操作が検出された場合、 直接操作 は WM/_POINTERCAPTURECHANGED メッセージを送信して、入力が直接操作によって処理されていることをクライアントに通知します。 ビューポートの状態が RUNNING に設定され、出力変換が更新されます。
- 操作以外の操作が検出された場合、 直接操作 は残りのメッセージを UI スレッドに送信します。
実行中のビューポート (RUNNING または INERTIA の状態) の場合、ウィンドウ メッセージは最初にデリゲート スレッドに到達します。ここで、 直接操作 は実行中のすべてのビューポートに対してテストを実行します。 直接操作では、ヒット テストによって識別された適切なビューポートに連絡先が自動的に割り当てられます。 ビューポートの状態は RUNNING で、出力変換が更新されます。
場合によっては、アプリケーション UI スレッドが遅すぎてヒット テストに応答できない場合があります。 ヒット テスト スレッド (RegisterHitTestTarget) を使用して、クライアントが WM/_POINTERDOWN および DM/_POINTERHITTEST メッセージを特定のスレッドに移動してヒット テストを可能にすることができます。
注釈
通常、 直接操作 は WM/_POINTERDOWN および DM/_POINTERHITTEST メッセージのみを UI スレッドに送信し、クライアントからの応答を待機している間、後のメッセージを源泉徴収します。 クライアントが SetContact を呼び出す場合、操作が検出されたときに UI スレッドが受け取るメッセージは WM/_POINTERDOWN と DM/_POINTERHITTEST、 WM/_POINTERCAPTURECHANGED メッセージのみです。
WM/_POINTERDOWN および DM/_POINTERHITTEST メッセージを処理するときに、クライアントが SetContact を呼び出さない場合があります。 この場合、 直接操作 は、操作があるかどうかを確認するためにメッセージを分析せずに、すべてのメッセージを UI スレッドに送信します。 その後、クライアントは SetContact を呼び出す任意のポイントを選択し、直接操作で操作の検出を開始し、 検出されたときに WM/_POINTERCAPTURECHANGED メッセージ メッセージ を送信できます。
Windows 10以降:WM/_POINTERDOWN または DM/_POINTERHITTEST メッセージで SetContact を呼び出す前に DeferContact を呼び出して、処理する操作を決定できます。 DeferContact を使用すると、後続のすべてのメッセージが、指定した期間 UI スレッドに送信されます。