Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registering a Global HotKey without disabling its key

I want to make a program that can catch keyboard events even if it's not active on any moment. Hooks were too complicated with all the things I have to do to make it to work (making a DLL, reading it, etcetera) so I decided to go on using hotkeys.

But now I have a problem. Registering the hotkey disables the key on the keyboard, thus I can only send the key to the program, while I can't type on any other program (e.g. Notepad).

This is my code:

#include <iostream>
#include <windows.h>
using namespace std;

int main(int argc, char* argv[]) {
    RegisterHotKey(NULL, 1, NULL, 0x41); //Register A
    MSG msg = {0};

    while (GetMessageA(&msg, NULL, 0, 0) != 0) {
        if (msg.message == WM_HOTKEY) {
            cout << "A"; //Print A if I pressed it
        }
    }

    UnregisterHotKey(NULL, 1);
    return 0;
}

// and now I can't type A's

Is there any simple solution to this problem? Thank you

like image 944
SmRndGuy Avatar asked Oct 12 '25 07:10

SmRndGuy


1 Answers

I would let your program simulate a keypress which equals the one you actually performed. That means:

  1. You press 'A'.
  2. The program catches the 'A'.
  3. The program simulates the keypress.

It's quite simple. The only problem would be that your program would also catch the simulated keypress. To avoid it, you can do the following:

  1. You press 'A'.
  2. The program catches the 'A'.
  3. The program unregisters the hotkey.
  4. The program simulates the keypress.
  5. (The program does not (!) catch the 'A'.)
  6. The program registers the hotkey again.

That's the whole loop.

Now, to simulate the keypress, you need to add some additional code. Have a look at this:

#include <iostream>
#include <windows.h>
using namespace std;

int main(int argc, char* argv[]) {
    RegisterHotKey(NULL, 1, 0, 0x41);            //Register A; Third argument should also be "0" instead of "NULL", so it is not seen as pointer argument
    MSG msg = {0};
    INPUT ip;
    ip.type = INPUT_KEYBOARD;
    ip.ki.wScan = 0;
    ip.ki.time = 0;
    ip.ki.dwExtraInfo = 0;
    ip.ki.wVk = 0x41;                            //The key to be pressed is A.

    while (GetMessage(&msg, NULL, 0, 0) != 0) {
        if (msg.message == WM_HOTKEY) {
            UnregisterHotKey(NULL, 1);           //Prevents the loop from caring about the following
            ip.ki.dwFlags = 0;                   //Prepares key down
            SendInput(1, &ip, sizeof(INPUT));    //Key down
            ip.ki.dwFlags = KEYEVENTF_KEYUP;     //Prepares key up
            SendInput(1, &ip, sizeof(INPUT));    //Key up
            cout << "A";                         //Print A if I pressed it
            RegisterHotKey(NULL, 1, 0, 0x41);    //you know...
        }
    }

    UnregisterHotKey(NULL, 1);
    return 0;
}

I tried it and it works fine, I guess. Hope I could help ;)


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!