Global keyboard hook with WH_KEYBOARD_LL and keybd_event (windows)

前端 未结 3 1238
无人共我
无人共我 2020-12-30 09:38

I am trying to write a simple global keyboard hook program to redirect some keys. For example, when the program is executed, I press \'a\' on the keyboard, the program can d

相关标签:
3条回答
  • 2020-12-30 09:49

    First one is easy. You get one for key down and another for key up. :)

    As for the why it can work without a DLL - that's because it is a global hook. Unlike thread-specific ones it is executed in your own process, not in the process where keyboard event happened. It is done via message sending to the thread which has installed the hook - that's precisely why you need message loop here. Without it your hook can't be ran as there would be no one to listen for incoming messages.

    The DLL is required for thread-specific hooks because they're called in the context of another process. For this to work, your DLL should be injected into that process. It is just not the case here.

    0 讨论(0)
  • 2020-12-30 09:53
    1. I have run your code but nothing happend? What wrong with me?
    2. Base on msdn that WH_KEYBOARD_LL message is "Global only" It mean more than that.

      The system calls this function .every time a new keyboard input event is about to be posted into a thread input queue. This message is special case. You also need an DLL to make a real global hook for other message.

    0 讨论(0)
  • 2020-12-30 09:54

    Your callback function execute twice because of WM_KEYDOWN and WM_KEYUP. When you down a key of your keyboard, windows calls the callback function with WM_KEYDOWN message and when you release the key, windows calls the callback function with WM_KEYUP message. That's why your callback function execute twice.

    You should change your switch statement to this:

    switch (wParam)
    {
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
            PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
            if (fEatKeystroke = (p->vkCode == 0x41))  //redirect a to b
            {     
                printf("Hello a\n");
    
                if ( (wParam == WM_KEYDOWN) || (wParam == WM_SYSKEYDOWN) ) // Keydown
                {
                    keybd_event('B', 0, 0, 0);
                }
                else if ( (wParam == WM_KEYUP) || (wParam == WM_SYSKEYUP) ) // Keyup
                {
                    keybd_event('B', 0, KEYEVENTF_KEYUP, 0);
                }
                break;
            }
            break;
    }
    

    About your second question, I think you have already got from @Ivan Danilov answer.

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