-1

I have read the msdn link, and tried to approach the GetMessage() function in the following keylogger-code .

In my smallest version of a program attached below, why isn't GetMessage() releasing and print "new message" if I press keyboard or resize window?

#include <stdio.h>
#inlcude <stdlib.h>
#inlcude <windows.h>

int main() {
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) != 0) {
        printf("\nnew message!");
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

UPDATE: As you mentioned I gave the process a window(handle) and it worked fine during I kept the GetMessage() within the WinMain. Because there should be other functionality I need to outsource the GetMessage() to its own thread as shown below. Unfortunately the GetMessage() function hangs up again, even though I specify the window-handle for which the messages should be recieved within its parameters. Any hints to get me further in understanding this function?

void control(HWND hwnd) {
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) != 0) {
        printf("\nnew message!");
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // window class creation
    const char window_name[] = "myWindow";
    WNDCLASSEX wc;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = window_name;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    // register the class
    if(!RegisterClassEx(&wc)) {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // window creation
    HWND hwnd;
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, window_name, "The Window Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);
    if(hwnd == NULL) {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // show window
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // threading
    HANDLE thread
    thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE*) control, hwnd, 0, NULL);

    WaitForSingleObject(thread, INFINITE);
    return 0;
    }
Linz
  • 9
  • 5
  • Because console applications don't use the windows message queue to handle such events. – David Heffernan Jan 04 '18 at 12:11
  • 1
    because `GetMessage` *Retrieves a message from the calling thread's message queue* - your thread have no any windows and nobody send mesages for it – RbMm Jan 04 '18 at 12:11
  • 1
    A low-level keyboard hook requires the message loop so that the OS knows that it can safely call the hook callback function. It will only ever make that call when GetMessage() is running. So you just stopped too soon, you forgot to add the SetWindowsHookEx code. – Hans Passant Jan 04 '18 at 12:26
  • Thanks for your answers. I have updated the code as it needed a handle as mentioned. Outsourcing the hole now hangs up the function again. Any help for this? – Linz Jan 05 '18 at 15:56

1 Answers1

0

Your program has not windows attached to it. As you use printf and main, I assume that it is a console program. In that case, windows messages (like keyboard events) are processed by the console hosting your own program which then feeds your stdin and display what it gets from your stdout/stderr.

To be able to use a message loop, the common way is to first create a window. If you do not, you will only get messages explicitely sent to the thread from another program that would knows about it.

I'm sorry this is only hints, but a complete and detailed explaination would be far beyond a SO answer...

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • 1
    So then, why answer at all instead of voting to close, e.g. because the question is *"too broad"*? – IInspectable Jan 04 '18 at 14:25
  • @IInspectable: I thought that my answer could help OP to understand why he was misusing a message loop. But showing a complete code demonstrating a correct message loop is really too much. – Serge Ballesta Jan 04 '18 at 15:33
  • Thanks for your answers. I have updated the code as it needed a handle as mentioned. Outsourcing the hole now hangs up the function again. Any help for this? – Linz Jan 05 '18 at 15:46