作成しているプログラムが所有していないプロセスにメイン ウィンドウがあります。Windows Hook
このメイン ウィンドウに子ウィンドウを追加する目的で、このプロセスに DLL を挿入するために使用しています。
私の最終目標はWS_EX_LAYERED
、内部に色付きの境界線を作成できるが、中央部分を透明にしてマウス クリックを許可するウィンドウを作成することでした。この部分は完全に機能します。
WNDCLASS wndClass = {};
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = OverlayProc;
wndClass.hInstance = g_TargetInstance;
wndClass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 255, 255));
wndClass.lpszClassName = "OVERLAY";
RegisterClass(&wndClass);
g_Window = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, "OVERLAY", nullptr,
WS_CHILDWINDOW, rect.left, rect.top, rect.right+1, rect.bottom+1, data->hwnd, nullptr, g_TargetInstance, nullptr);
SetLayeredWindowAttributes(g_Window, RGB(0, 255, 255), 0, LWA_COLORKEY);
ShowWindow(g_Window, SW_SHOW);
UpdateWindow(g_Window);
これの 2 番目の部分は、親ウィンドウへのすべてのマウス入力を条件付きでブロックしたかったことです。WS_EX_LAYERED
ウィンドウの透明部分ではこれを行うことができなかったのでSTATIC
、メイン ウィンドウの子として2 番目の透明コントロールを作成しようとしましたが、これもマウス入力をブロックしません。
また、シミュレートされたマウス クリックを、 への呼び出しPostMessage
、引き渡しWM_LBUTTONDOWN
、およびを介して親ウィンドウに送信していますWM_LBUTTONUP
。透明なウィンドウを介して親ウィンドウへのすべてのマウス入力をブロックするにはどうすればよいですか?
これは、兄弟コントロール上に描画された単純な透明ウィンドウでは実行できないようです。私が行ったことは、メイン ウィンドウの WndProc 関数を置き換えてマウス メッセージをインターセプトするために使用するプロセスにフックSetWindowHookEx
を追加するWH_GETMESSAGE
ために使用することでした。シミュレートされたマウス メッセージにwParam
引数の特定の値をタグ付けして、プロシージャがシミュレートされ、その値を削除して、親ウィンドウに渡します。
クリック メッセージで「タグ」値が検出されない場合、マウス メッセージを飲み込み、元の WndProc 関数に渡しません。
インジェクションされた WndProc 置換
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
case WM_LBUTTONDOWN:
wParam -= 11141008;
if (wParam != MK_LBUTTON && !g_Paused)
return 0;
break;
case WM_LBUTTONUP:
wParam -= 11141008;
if (wParam != 0 && !g_Paused)
return 0;
break;
case WM_MOUSEHOVER:
case WM_MOUSEMOVE:
if (!g_Paused)
return 0;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
Windows フック関数のスニペット
//...
switch (data->message)
{
case (WM_USER + 1):
{
g_Paused = FALSE;
//...
SetWindowSubclass(data->hwnd, WndProc, 1, 0);
break;
}
case (WM_USER + 2):
{
RemoveWindowSubclass(data->hwnd, WndProc, 1);
//...
break;
}
}
//...
ウィンドウ フック関数内のコードを使用して、メイン プロセス ウィンドウをサブクラス化し、独自の WndProc 関数を挿入して、マウス入力を希望どおりに処理します。
これは、ウィンドウを物理的にクリックせずにマウス クリックを「シミュレート」するために使用されるコードです。wParam
このクリックがシミュレートされたものであり、ユーザーが生成したものではないことを識別するための付加価値に注意してください。
void Window::LeftClick(DWORD x, DWORD y, DWORD delayMillis)
{
LPARAM lparam = MAKELPARAM(x, y);
lock_guard<mutex> lock(this->m_ClickMutex);
PostMessage(this->m_Window, WM_LBUTTONDOWN, 11141008 + MK_LBUTTON, lparam);
this_thread::sleep_for(std::chrono::milliseconds(delayMillis));
PostMessage(this->m_Window, WM_LBUTTONUP, 11141008, lparam);
}
また、私の言葉の選択をridrid笑し、キーボード入力をシミュレートするsimulated
ために使用PostMessage
することに対する追加の批判をridrid笑していたコメントの人のために、(私の目的のために)完璧かつ非常に確実に機能する私のキーボード入力テスト方法を次に示します。
void GameWindow::KeyPress(UINT vkCode) const
{
UINT scanCode = MapVirtualKey(vkCode, MAPVK_VK_TO_VSC);
LPARAM lparam1 = MAKELPARAM(1, scanCode);
LPARAM lparam2 = MAKELPARAM(1, 0xC000 | scanCode);
PostMessage(this->m_Window, WM_KEYDOWN, vkCode, lparam1);
this_thread::sleep_for(chrono::milliseconds(25));
PostMessage(this->m_Window, WM_KEYUP, vkCode, lparam2);
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加