ユーザーが画面に触れたときに表示されるアプリを作りたいです。クリックでは機能しないはずです。Windows7/8でタッチハンドルを探しました。しかし、すべてのタッチウィンドウをRegisterTouchWindowに登録する必要があることがわかりました
TL; DR
タッチポイントの位置をウィンドウの外側に(グローバルに)取得する方法はありますか?
Win 8アプリでは、RegisterTouchWindowは不要になりました。
私の知る限り、目的を達成する方法はいくつかありますが、いくつかの制限があります。
この記事は、Win 7と8の両方で機能します。ただし、タッチスクリーンのベンダーIDと製品IDが必要です。一部のタッチデバイスでは、アプリケーションが正しく動作しない可能性があります。
Win 8でRegisterPointerInputTargetを使用します。私のデバッグによると、Windows8のタッチメカニズムには独自の特徴があります。タッチダウンとタッチアップの間、ウィンドウが最小化されているか、別のウィンドウで覆われているか、後の期間でWS_EX_TRANSPARENT属性が設定されているかに関係なく、すべてのタッチイベントが最初のタッチイベントを受信するウィンドウに送信されます。1回押してから離すまでのタッチイベントは、最初のウィンドウが破棄された場合にのみ別のウィンドウと共有できます。このAPIを使用すると、すべてのタッチイベントが登録済みウィンドウに送信されます。UnregisterPointerInputTargetが登録されたウィンドウによって呼び出されるか、 InjectTouchInputを使用してタッチ入力がシステムに注入されるまで、他のウィンドウはタッチイベントを受信できなくなります。。「登録された入力ターゲットによって注入された入力は傍受されません。」このAPIを使用するには、UIアクセス権限が必要であることに注意してください。サンプルはここにあります。
Windowsフック。Win 7/8のデスクトップアプリの場合、タッチイベントはWH_CALLWNDPROCまたはWH_GETMESSAGEでSetWindowsHookExを使用して簡単にフックできます。Win 8のメトロアプリの場合、ウィンドウのメッセージループで検出できるのは最初のポインターイベントのみです。ポインタイベントはクリックまたはタップのいずれかで発生する可能性がありますが、GetPointerTypeは、それがタッチポインタであるかマウスポインタであるかを示します。フックを使用するためのサンプルは、ここにあります。
ポインタイベントを処理するためのコードスニペット:
switch(Msg)
{
...
case WM_POINTERENTER:
case WM_NCPOINTERDOWN:
case WM_NCPOINTERUP:
case WM_NCPOINTERUPDATE:
case WM_POINTERACTIVATE:
case WM_POINTERCAPTURECHANGED:
case WM_POINTERDOWN:
case WM_POINTERLEAVE:
case WM_POINTERUP:
case WM_POINTERUPDATE:
{
UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
POINTER_INPUT_TYPE pointerType;
if (GetPointerType(pointerId, &pointerType))
{
if (pointerType == PT_TOUCH)
{
...
}
}
}
break;
...