c++ - 确定消息发送到哪个窗口(SetWindowsHookEx & WH_KEYBOARD)

标签 c++ c winapi setwindowshookex

我需要能够确定该消息适用于哪个窗口,但我不知道如何正确执行此操作。在WH_MOUSE中有一个特殊的结构体(MOUSEHOOKSTRUCT)存储窗口的hwnd,但是在WH_KEYBOARD中从哪里获取hwnd呢?

LRESULT CALLBACK messageHandler(int nCode, WPARAM wParam, LPARAM lParam)
{
    // ???
}
 
DWORD WINAPI messageDispatcher(LPVOID thread)
{
    hookHandle = SetWindowsHookEx(WH_KEYBOARD, messageHandler, GetModuleHandle(nullptr), *reinterpret_cast<DWORD*>(thread));
 
    if (!hookHandle)
    {
        return GetLastError();
    }
 
    MSG message{};
 
    while (GetMessage(&message, 0, 0, 0) > 0)
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }
 
    return 0;
}

理论上,我可以使用GetForegroundWindow,但在我看来,这是一个糟糕的选择,因为窗口可以从其他进程接收键盘消息(如果另一个进程发送 >SendMessage 到此窗口),而不是当前窗口正是消息所要发送的窗口这一事实。

最佳答案

生成键盘操作时,操作系统尚不知道哪个窗口最终会收到该消息。这就是为什么 WH_KEYBOARD Hook 不像 WH_MOUSE Hook 那样提供目标 HWND(因为鼠标消息携带与窗口相关的坐标) )。

当键盘消息被路由到目标时,该消息将被传递到当前具有输入焦点的窗口。

About Keyboard Input :

The system posts keyboard messages to the message queue of the foreground thread that created the window with the keyboard focus. The keyboard focus is a temporary property of a window. The system shares the keyboard among all windows on the display by shifting the keyboard focus, at the user's direction, from one window to another. The window that has the keyboard focus receives (from the message queue of the thread that created it) all keyboard messages until the focus changes to a different window.

由于您的钩子(Hook)在目标线程的消息队列内部运行,因此您可以使用 GetFocus()获取当时的目标HWND:

Retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue.

否则,您可以使用 WH_CALLWNDPROC/RET Hook 来代替,该 Hook 在消息实际传递到窗口时被调用。但是,您无法使用此 Hook 阻止消息(正如您在 previous question 中询问的那样)。

关于c++ - 确定消息发送到哪个窗口(SetWindowsHookEx & WH_KEYBOARD),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70206640/

相关文章:

c++ - 指针数组和类型转换

c++ - std::transform 与 std::istream_iterator

c - section 和 task openmp 的区别

从位图和透明度颜色创建蒙版 - Windows GDI

c++ - 提供赋值运算符但没有复制构造函数

c++ - C++ 中结构的奇怪行为 [第 1 部分]

c - libc 如何提供具有两个名称的函数?

c - 将整数类型转换为指向c中整数的指针

winapi - 如何在 COM-Addin (Outlook <=2003) 内部打开 WordMail 时可靠地确定给定 Outlook 检查器窗口的窗口句柄?

定期时间调整更改的 Windows 通知