Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Determine which window the message was sent (SetWindowsHookEx & WH_KEYBOARD)

I need to be able to determine which window the message is intended for, but I don’t understand how to do it correctly. In WH_MOUSE has a special structure (MOUSEHOOKSTRUCT) that stores the hwnd of the window, but where to get the hwnd in WH_KEYBOARD?

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;
}

In theory, I could use GetForegroundWindow, but it seems to me that this is a terrible option, because the window can receive a keyboard message from some other process (if another process sends a SendMessage to this window) and not the fact that the current window will be exactly the one for which the message was intended.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

At the time a keyboard action is generated, the OS doesn’t know yet which window will eventually receive the message. That is why the WH_KEYBOARD hook doesn’t provide a target HWND, like a WH_MOUSE hook does (since a mouse message carries window-related coordinates).

When a keyboard message is being routed to a target, the message gets delivered to the window that currently has input focus.

Per 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.

Since your hook runs inside of the message queue of the target thread, you can use GetFocus() to get the target HWND at that time:

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

Otherwise, you can use a WH_CALLWNDPROC/RET hook instead, which gets called when the message is actually delivered to a window. However, you can’t block messages with this hook (as you were asking about in your previous question).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading