1

I am new to the Win32 API. I am writing a C++ code which installs keyboard and mouse hooks, and to keep running code I am using a message loop.

To my understanding, GetMessage() gets the message from the message queue and dispatches it for further processing, but in the below code even if I am not using the while loop, just storing the value of GetMessage(), my code still keeps running and I am getting mouse and keyboard codes.

My doubt is if I am not using the while loop, GetMessage() should get the first message from the message queue and then it should cout and unhook both hooks and exit the code normally, but the code is not behaving like this.

This is the code which I have written:

#include <iostream>
#include <Windows.h>
using namespace std;

HHOOK keyboardHook;
HHOOK mouseHook;

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HC_ACTION && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) {
        KBDLLHOOKSTRUCT* pKeyStruct = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
        DWORD keyCode = pKeyStruct->vkCode;
        std::cout << "Key Pressed: " << keyCode << std::endl;

        if (keyCode == VK_ESCAPE) {
            PostQuitMessage(0);
        }
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HC_ACTION && wParam == WM_MOUSEMOVE) {
        MSLLHOOKSTRUCT* pMouseStruct = reinterpret_cast<MSLLHOOKSTRUCT*>(lParam);
        int x = pMouseStruct->pt.x;
        int y = pMouseStruct->pt.y;
        std::cout << "Mouse Move: x=" << x << ", y=" << y << std::endl;
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int main() {
    keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
    mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, NULL, 0);

    MSG msg;
    // while (GetMessage(&msg, NULL, 0, 0) > 0) {
    //     TranslateMessage(&msg);
    //     DispatchMessage(&msg);
    // }
    int a = GetMessage(&msg, NULL, 0, 0);
    cout<<a;
    UnhookWindowsHookEx(keyboardHook);
    UnhookWindowsHookEx(mouseHook);
    return 0;
}
7
  • if you never receive any messages then GetMessage will block forever and doesn't need to be in a loop Commented Jun 20, 2023 at 6:56
  • 1
    When can a thread receive window messages? Key takeaway: GetMessage can dispatch messages without ever returning. Commented Jun 20, 2023 at 7:46
  • 1
    @JemishVirani GetMessage() blocks until there is an application-level message worth returning to the caller. In the meantime, it dispatches internal system messages without returning to the caller. The OS can use the message queue for its own purposes, and hooks are one of several features that internally use private system messages. Commented Jun 20, 2023 at 15:24
  • 1
    The meaningful distinction here is between queued ("posted") and non-queued ("sent") messages. GetMessage will only ever return queued messages to the caller. For low-level input hooks the system sends messages, so they are never returned to the caller of GetMessage. Instead, GetMessage dispatches inbound cross-thread sent messages internally. Commented Jun 20, 2023 at 20:10
  • 1
    You didn't call CreateWindow() to create your own window. So GetMessage() never has anything to return. And blocks, otherwise keeping the hooks alive. The primary need of GetMessage here is to tell the OS that your app is idle, so the OS can safely make the callbacks without risking re-entrancy problems. Commented Jun 21, 2023 at 1:19

1 Answer 1

0

I agree with the community:

Refer to the Blog: When can a thread receive window messages?

Everybody who has messed with window messaging knows that GetMessage and PeekMessage retrieve queued messages, which are dispatched to windows via DispatchMessage. Most people also know that GetMessage and PeekMessage will also dispatch nonqueued messages. (All pending nonqueued messages are dispatched, then the first queued message is returned.) But apparently not many people realize that SendMessage will also dispatch messages!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.