0

在GUI自动化服务的开发中,我们的团队面临着无法正确处理WM_LBUTTONUP消息的问题。

目标是拦截 WM_LBUTTONUP,禁用活动窗口,完成我们的工作并显示带有 YES 和 NO 按钮的 MessageBox:

  1. 如果点击是,我们手动做我们的事情;
  2. 否则,如果单击 NO,则不执行任何操作,但在这两种情况下,我们都必须阻止单击的窗口接收此消息,然后启用冻结窗口。

尝试使用 WH_MOUSE_LL 钩子,但点击的窗口在我们可以做任何事情之前收到点击。尝试使用 WH_GETMESSAGE 钩子,我们做所有事情,但在启用接收 WM_LBUTTONUP 后,用户独立回答禁用的窗口。

消息循环的代码(在 Service.exe 中):

int Loop()
{
    do
    {
        if (PeekMessage(&MessagesQueue, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&MessagesQueue);
            DispatchMessage(&MessagesQueue);
        }
    } while (true);
    ResetHook();
    return (int)MessagesQueue.wParam;
}

与 WH_MOUSE_LL 一起使用的代码(在 Service.dll 中):

LRESULT __stdcall HookProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (wParam == WM_LBUTTONUP && GetAsyncKeyState(VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1))
    {
        HWND w = GetForegroundWindow();
        EnableWindow(w, FALSE);
        // Do things right.
        EnableWindow(w, TRUE);
        SetForegroundWindow(w);
    }
    return CallNextHookEx(MouseHook, code, wParam, lParam);
}

HRESULT SetHook()
{
    MouseHook = SetWindowsHookExW(WH_MOUSE_LL, HookProc, hDllModule, 0);
    if (MouseHook == NULL)
    {
        wcout << L"MouseHook = NULL" << endl;
    }
    else
    {
        wcout << L"MouseHook is" << endl;
    }
    return (MouseHook == NULL) ? ::GetLastError() : NO_ERROR;
}

void ResetHook()
{
    UnhookWindowsHookEx(MouseHook);
}

以及与 WH_GETMESSAGE 一起使用的代码(在 Service.dll 中):

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    MSG* msg = (MSG*)lParam;
    if (msg->message == WM_LBUTTONUP && GetAsyncKeyState(VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1))
    {
        HWND w = GetForegroundWindow();
        EnableWindow(w, FALSE);
        // Do things right.
        EnableWindow(w, TRUE);
        SetForegroundWindow(w);
    }
}

所以我的问题是如何拦截 WM_LBUTTONUP 消息并阻止目标窗口接收到该消息?

4

0 回答 0