0

I am trying to hook all mouse move events but I never reciever any message. This is whole code:

#include <Windows.h>
#include <windowsx.h>
#include <iostream>

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (wParam != WM_MOUSEMOVE)
    {
        return CallNextHookEx(NULL, nCode, wParam, lParam);
    }

    std::cout << GET_X_LPARAM(lParam) << std::endl;
    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_MOUSEMOVE:
        int xPos = GET_X_LPARAM(lParam);
        int yPos = GET_Y_LPARAM(lParam);
        std::cout << xPos << " - " << yPos << std::endl;
        return 0;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
{
    AllocConsole();

    HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hInstance, NULL);

    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}
3
  • For a global hook, your hook procedure must be in a loadable module (DLL). Your MouseHookProc should always call CallNextHookEx unless you wish to filter out the message altogether. In the latter case your hook procedure should return a nonzero value. Failing to meet the requirements will break other hooks in the system. Make sure to read LowLevelMouseProc thoroughly. Everything I just said is spelled out there. Commented Jun 7, 2014 at 18:12
  • @IInspectable asker is using low level hook Commented Jun 8, 2014 at 6:29
  • @David Good point. For a low level hook the hook procedure is not required to reside in a DLL. The remaining requirements still hold, and the MouseHookProc needs to be fixed. Commented Jun 8, 2014 at 10:44

3 Answers 3

3
   std::cout << GET_X_LPARAM(lParam) << std::endl;

The hook works fine, you are just overrating the ability of the CRT to initialize stdout correctly when you build a program that does not have a console. The hook callback code is in general not correct. You'll light it up like this:

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode >= 0 && wParam == WM_MOUSEMOVE) {
        MSLLHOOKSTRUCT* mh = (MSLLHOOKSTRUCT*)lParam;
        std::stringstream ss;
        ss << mh->pt.x << ", " << mh->pt.y << std::endl;
        OutputDebugStringA(ss.str().c_str());
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

You'll see text appear in the debugger, for Visual Studio it will show up in the Output window.

Another way to do this is to simply build a console mode app so you get the console right away and stdout will work. Change WinMain() to main().

Or by re-opening stdout, probably what you prefer. Like this:

  AllocConsole();
  freopen("CONOUT$", "wb", stdout);
Sign up to request clarification or add additional context in comments.

Comments

1

If you're trying to capture mouse events for ALL processes (your NULL last parameter implies that), you need a system wide hook in a DLL.

I have an example on my website here.

2 Comments

That's not correct, the low-level mouse hook never uses a DLL.
Ahh, didn't spot it was a low level one.
0

yes like @HansPassant mentioned std::cout is not efficient way to display things unless u make your console refresh each time it's updated.

I have remade the whole program, because I needed too, using code:blocks default win32 template and replaced MouseHookProc :)

#include <windows.h>
#include <windowsx.h>
#include <iostream>
#include <sstream>

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam);

char szClassName[ ] = "CodeBlocksWindowsApp";
HWND Label1, Label2; //adding 2 static controls to display things

int WINAPI WinMain (HINSTANCE hThisInstance,
                 HINSTANCE hPrevInstance,
                 LPSTR lpszArgument,
                 int nCmdShow)
{
// adding hook
HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hThisInstance, NULL);

HWND hwnd;
MSG messages;
WNDCLASSEX wincl;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

if (!RegisterClassEx (&wincl))
    return 0;

hwnd = CreateWindowEx (0, szClassName, "Code::Blocks Template Windows App", 
       WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, 
       HWND_DESKTOP, NULL, hThisInstance, NULL);

ShowWindow (hwnd, nCmdShow);

while (GetMessage (&messages, NULL, 0, 0))
{
    TranslateMessage(&messages);
    DispatchMessage(&messages);
}

return messages.wParam;
}


LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
    case WM_CREATE:
        //creating those 2 static controls
        Label1 = CreateWindow("STATIC", "Label1", WS_VISIBLE | WS_CHILD, 10,10,60,18, hwnd, NULL, NULL, NULL);
        Label2 = CreateWindow("STATIC", "Label2", WS_VISIBLE | WS_CHILD, 70,10,60,18, hwnd, NULL, NULL, NULL);
    break;
    //adding mousemove event
    case WM_MOUSEMOVE: {
        int xPos = GET_X_LPARAM(lParam);
        int yPos = GET_Y_LPARAM(lParam);
        //std::cout << xPos << " - " << yPos << std::endl;
        TCHAR Coords[20];
        wsprintf(Coords, "%i, %i", xPos, yPos);
        SetWindowText(Label1, Coords);
    return 0; }

    case WM_DESTROY:
        PostQuitMessage (0);
        break;
    default:
        return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}

//replacing MouseHookProc
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode >= 0 && wParam == WM_MOUSEMOVE) {
        MSLLHOOKSTRUCT* mh = (MSLLHOOKSTRUCT*)lParam;
        std::stringstream ss;
        ss << mh->pt.x << ", " << mh->pt.y << std::endl;
        //OutputDebugStringA(ss.str().c_str());
        SetWindowText(Label2, ss.str().c_str());
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

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.