SetWindowsHookEx for WH_MOUSE

28,594

Solution 1

// here I put WH_MOUSE instead of WH_MOUSE_LL
hMouseHook = SetWindowsHookEx( WH_MOUSE_LL, mouseProc, hInstance, NULL );

Fourth param must also be changed to GetCurrentThreadId() to make it local.

Solution 2

since you have a "main" in there, my guess is that you'd need to make it into a dll for it to work for messages other than the *_LL type

Understanding the low-level mouse and keyboard hook (win32)

http://developer-resource.blogspot.com/2008/07/setwindowshookex-example.html has a dll example

Share:
28,594
tobi
Author by

tobi

Interested in C++ programming language. Felt in love with graphics programming.

Updated on September 11, 2020

Comments

  • tobi
    tobi over 3 years

    I've got some code into my hands that prints coordinates of the mouse globally (using WH_MOUSE_LL). My target is to use WH_MOUSE instead of WH_MOUSE_LL because (from what I've read) it is faster. I've read over the forum that when using WH_MOUSE it needs to be declared in DLL to achieve global effect, but still, when used in the program it should work over that application where it was declared, but it doesn't work (it prints nothing) when I just change the WH_MOUSE_LL to WH_MOUSE. This is the code:

    #define _WIN32_WINNT 0x0400
    #pragma comment( lib, "user32.lib" )
    
    #include <windows.h>
    #include <stdio.h>
    
    HHOOK hMouseHook;
    
    LRESULT CALLBACK mouseProc (int nCode, WPARAM wParam, LPARAM lParam)
    {
        MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
        if (pMouseStruct != NULL){
            if(wParam == WM_LBUTTONDOWN)
            {
                printf( "clicked" ); 
            }
            printf("Mouse position X = %d  Mouse Position Y = %d\n", pMouseStruct->pt.x,pMouseStruct->pt.y);
        }
        return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
    }
    
    DWORD WINAPI MyMouseLogger(LPVOID lpParm)
    {
        HINSTANCE hInstance = GetModuleHandle(NULL);
    
        // here I put WH_MOUSE instead of WH_MOUSE_LL
        hMouseHook = SetWindowsHookEx( WH_MOUSE_LL, mouseProc, hInstance, NULL );
    
        MSG message;
        while (GetMessage(&message,NULL,0,0)) {
            TranslateMessage( &message );
            DispatchMessage( &message );
        }
    
        UnhookWindowsHookEx(hMouseHook);
        return 0;
    }
    
    int main(int argc, char** argv)
    {
        HANDLE hThread;
        DWORD dwThread;
    
        hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)MyMouseLogger, (LPVOID) argv[0], NULL, &dwThread);
        if (hThread)
            return WaitForSingleObject(hThread,INFINITE);
        else
            return 1;
    
    }
    
  • tobi
    tobi almost 12 years
    Hey, thanks for interest. I changed it to: hMouseHook = SetWindowsHookEx( WH_MOUSE, mouseProc, hInstance, GetCurrentThreadId() ); but it still doesn't work (it still doesn't print anything when I move my mouse over the command line). Sorry for just begging for a solution, but I completely don't know how to do that.
  • Yuhong Bao
    Yuhong Bao almost 12 years
    A console app is not the best kind of app to test things like this. The console window is in another process. Try creating a new window via CreateWindow if you want to test.
  • tobi
    tobi almost 12 years
    thanks, I have an another question. From what I've read by putting the hook into a DLL it injects processes. Does it mean that capturing the mouse will work on my desktop, menu start etc. too? What about title bar of applications? I've seen some posts over the Internet with such problems, but don't know if they failed with something or there's some kind of limitation (or another approach).
  • Yuhong Bao
    Yuhong Bao almost 12 years
    Should work. Global hooks applies to all processes including explorer.exe. Beware that 32-bit DLLs can only be injected into 32-bit processes and 64-bit DLLs can only be injected into 64-bit processes.