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

后端 未结 4 1165
借酒劲吻你
借酒劲吻你 2020-12-05 05:50

I\'m trying to capture global mouse and keyboard input.

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
  if (nCode >= 0) {
            


        
相关标签:
4条回答
  • 2020-12-05 06:04

    The problem is your message loop, it burns 100% CPU cycles because you use PeekMessage(). Windows knows how to keep the hook alive even if you don't poll for messages, use GetMessage() to solve your problem. Using Sleep(1) will solve your problem too but is not necessary here.

    Why must SetWindowsHookEx be used with a windows message queue

    0 讨论(0)
  • 2020-12-05 06:04

    Instead of doing:

    if (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
        printf("msg recvd\n");
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    Sleep(50);
    

    Switch this to:

    while (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
        // Add this potentially...
        if (msg.message == WM_QUIT)
            break;
        printf("msg recvd\n");
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    Sleep(10);
    

    This will allow your app to continue to process all messages in the queue until it's empty (like having no sleep), then give up some CPU time when the app is "idle".

    0 讨论(0)
  • 2020-12-05 06:11

    MouseHookProc should reside in dll, otherwise you can not capture "global" input ( http://msdn.microsoft.com/en-us/library/ms997537.aspx )

    About the loop - you can modify it like this:

    while(true) {
      MSG msg;
      while (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
        printf("msg recvd\n");
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
    #ifdef TEST
      DoStuff();
      Sleep(50);
    #endif
    }
    
    0 讨论(0)
  • 2020-12-05 06:20

    I aksed you whether you place the place MouseHookProc in DLL, because attempts to place it inside an EXE it is a typical error. I made it also many years ago.

    First of all, how you can read in http://msdn.microsoft.com/en-us/library/ms644990.aspx:

    SetWindowsHookEx can be used to inject a DLL into another process. A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have different names.

    So you must place in a DLL. To be exactly if you want support both 32-bit and 64-bit platforms you have to implement two dlls: one 32-bit and 64-bit DLL. But why? And how SetWindowsHookEx works?

    If you execute in an EXE the code like following

    HINSTANCE hinstDLL = LoadLibrary(TEXT("c:\\myapp\\syshook.dll"));
    HOOKPROC hkprcMouse = (HOOKPROC)GetProcAddress(hinstDLL, "MouseHookProc");
    HHOOK hhookMouse = SetWindowsHookEx( 
                        WH_MOUSE_LL,
                        hkprcMouse,
                        hinstDLL,
                        0); 
    

    you give user32.dll request to inject your syshook.dll in all other processes on the same windows station (dll will not be injected to services and processes of other users logged through fast user switching). Then user32.dll call LoadLibrary to the syshook.dll in different processes. Then if the function MouseHookProc will be called, in will be called in the context of the process which proccess the mouse message. If the process is not a console application the code like

    printf("right mouse down\n");
    

    can not work.

    So I hope now you will undestend why you must place MouseHookProc in a DLL.

    0 讨论(0)
提交回复
热议问题