このようなことを行うための「古典的な」方法-Spy++や、調べたり操作したりするUIの一部を選択できる他のさまざまなアプリで使用される-は次のようになります:(これはC ++ /Win32APIポイントから書かれていますビューですが、WindowFromPointとGetAncestorを除いて、ほとんどのステップには.Netと同等のものがあります)
- 十字線を表示し、WM_LBUTTONDOWN/Control.MouseDownに応答するUIをいくつか用意します。
- マウスクリックすると、
- SetCapture / Control.Captureを使用して、マウスを「キャプチャ」します。これは、左ボタンが押されている限り、HWNDがそれ以降のすべてのマウス移動イベントを受信するようにする魔法の部分です。(これは、フックなどが必要ないことを意味します。)、
- SetCursorを使用して、カーソルを十字線などの適切なものに設定します。
- どこかにフラグを設定して、ドラッグ/キャプチャ中に取得しようとしているマウス移動イベントと、ユーザーが通常どおりコントロール上でマウスを動かした場合に取得するマウス移動イベントを区別できるようにします。
- これで、ユーザーが十字ポインターを画面上で動かすと、WM_MOUSEMOVE / Control.MouseMoveイベントが発生します。前に設定したフラグをチェックして、これが「ドラッグ中」であることを確認してください。ClientToScreen / Control.PointToScreenを使用して、moveイベントのコントロール相対座標から画面座標を取得し、WindowFromPointを使用してその位置で最も子のウィンドウを取得し、GetAncestor(GA_ROOT)を使用して最上位ウィンドウを取得します。気になる場合は、ウィンドウにWS_CAPTIONが設定されているかどうかを確認して、タイトルバーのあるウィンドウであることを確認してください。(タスクバーとデスクトップウィンドウも除外することをお勧めします。)GetWindowThreadProcessIDなどのAPIを使用して、独自のプロセスからウィンドウを除外することもできます。HWNDが実行可能な候補である場合は、どこかに保存してください。UIがまだ存在する場合は、
- ユーザーがマウスの位置を離すと、WM_LBUTTONUP/Control.MouseUpが表示されます。ユーザーはドラッグを終了します。ReleaseCaptureを選択し、アイコンとカーソルをユーザーがマウスを押す前の状態に戻します。次に、保存されているHWND(存在する場合)を使用します。
操作をキャンセルするためにドラッグ中にESCも処理することも礼儀正しいと見なされます。
また、上記はキーボードに対応していません。また、アプリの存続期間中または選択ダイアログが表示されているときに、RegisterHotkeyをいくつかのホットキーと一緒に使用し、他の返信で説明されているようにGetForegroundWindow()を使用してホットキーに応答することもお勧めします。