I am writing a win32 application that needs to take hotkeys while not on focus(it runs in the background without drawing a window). I use RegisterHotKey to assing a few keys but that blocks the for every other process. For example I assign the 'c' key and when I press it in notepad nothing happens.
-
1You asked to change what pressing 'C' should be interpreted as and now you're saying that you didn't mean to? If you want Notepad to consume the 'C' key as it should, don't register it as a hotkey. – IInspectable Sep 08 '13 at 16:11
-
I too am unclear on how your app is supposed to work. What are the real conditions on when your app is supposed to consume keystrokes? – Eric Brown Sep 08 '13 at 19:49
3 Answers
RegisterHotKey()
registers global hotkeys. Hotkeys are processed before regular keyboard input processing, meaning that if you register a hotkey successfully, pressing that key will result in you getting your hotkey message rather than the app with focus getting the normal WM_KEYDOWN
/WM_CHAR
messages. You have effectively blocked other apps from seeing that key press.
This is by design.
Obviously the solution to avoid clashes like you describe is to not register a hotkey that other applications may use. If you register C without any qualifiers as a hotkey, then no other program will see the C key being pressed. Instead you should use qualifiers like Ctrl/Shift/Alt to prevent your hotkey from interfering with the normal use of the keyboard.
There is no way to register a hotkey that's global unless some other program is active. If you want to achieve the situation where, say, your hotkey works while the desktop is active but nothing else is, you could use a message hook to inject code into the desktop's process (via SetWindowsHookEx()
) and intercept key presses that way. But you can't do it with RegisterHotKey()
.

- 36,172
- 4
- 64
- 79
I just tried UnregisterHotKey()
, simulated the key with keybd_event()
, then RegisterHotKey()
again. I don't recommend it as a production code, it's probably better to use hooks for that, but as a quick hack I just wanted to say that it works.

- 88
- 5
GetAsyncKeyState()
can be used to determine if certain keys are pressed, even when the program is running in the background.

- 87
- 7
-
1Polling is never a good idea. You will have to continuously call the API, and then you're still not guaranteed to get all keypresses. The API call will also fail if: *"The foreground thread belongs to another process and the desktop does not allow the hook or the journal record."* as documented [here](http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293.aspx). – IInspectable Sep 08 '13 at 18:20
-
If you have any better suggestions, please let me hear it. I dont get people who marks answers as unhelpful especially if they are the only answer on a question. But thank you for you _input_ – Hjorthenify Sep 08 '13 at 18:24
-
1@IInspectable So positive and supportive, as always *rolls eyes*. Up-voted answer - it worked just fine for me. – Mike Weir Sep 09 '13 at 01:44