Why does RegisterHotKey succeed with Ctrl-C? - windows

The docs for RegisterHotKey say:
RegisterHotKey fails if the keystrokes specified for the hot key have
already been registered by another hot key.
And yet registering Ctrl+C works.
Why? / How can I be notified that the hotkey is already in use (perhaps by some other function)?
EDIT
My goal it to have a user alerted to the fact that such a shortcut key is already in use and therefore they should choose a different one.

Ctrl+C is a system-defined key sequence, but it is not a pre-registered hotkey, from an application perspective. That is why an application is able to register a hotkey for it.
A hotkey is its own feature. Just because a given key sequence invokes a system action does not mean it is implemented in the system as an application-defined hotkey specifically. For instance, there is no WM_HOTKEY message generated for Ctrl+C unless it is explicitly registered by an application (WM_COPY is generated instead). Ctrl+Alt+Del is also not an application-defined hotkey either, for instance (and you can't register that).
If you want to detect/discard Ctrl+C without registering it as a hotkey, use a keyboard hook via SetWindowsHookEx().

Related

Windows Event_System_Foreground delivery order

Working in a plugin architecture (specifically, Sparx Systems Enterprise Architect), which does not forward either raw or cooked keyboard events, keyboard shortcuts for the plugin can be defined using RegisterHotKey(). These hotkeys are global, and the registration call fails if the specified key combination is already registered.
Since the application within which the plugin executes can be run in multiple instances, the hotkeys need to be repeatedly registered and unregistered based on which instance is in the foreground. An event hook for EVENT_SYSTEM_FOREGROUND can be set up for this purpose, but the question is: is there a guaranteed delivery order?
I need the instance that is losing focus to be told first so that it can unregister the hotkeys before the instance gaining focus tries to register them.
Is this possible? Or will I have to implement synchronization to be sure?
Windows DevCenter WM_ACTIVATE message says
..Sent to both the window being activated and the window being deactivated. If the windows use the same input queue, the message is sent synchronously, first to the window procedure of the top-level window being deactivated, then to the window procedure of the top-level window being activated. If the windows use different input queues, the message is sent asynchronously, so the window is activated immediately..
So if all of your windows come from the same application sharing the same input queue then it should be guaranteed. I guess that the EVENT_SYSTEM_FOREGROUND is built on top of the older code following the older logic (at least the implementation in ReactOS at http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/focus.c?view=markup (see EVENT_SYSTEM_FOREGROUND inside co_IntSetActiveWindow) does it)
Your problem might be easier if you'd monitor only keyboard events in your original hosting process (no global side effects) using the Windows DevCenter SetWindowsHookEx function, filter WH_KEYBOARD
In that case your code would exist once in one exe having one global variables, no cross-process synchronization would be needed

How can my Cocoa app receive global keyboard events even if it doesn't have focus?

I'm building a little app which needs to recognize if certain keys on the keyboard were pressed. In this case the arrow keys. The app must take action when these keys get pressed, even if it's not the frontmost and has no focus.
Is this possible to do? What would I have to do to receive these keyboard events no matter where they happen?
You do this by registering a hotkey using Carbon's RegisterEventHotKey function. There are also open source libraries available that make this easier, for example SGHotKeysLib.

What message will be sent by Windows when you press "Windows+D"

I used SPY++ to hook my windows message, but there is no WM_SYSCOMMAND message was sent when I pressed "Windows+D". What message will be sent by Windows when you press "Windows+D"?
Your application will not get a window message at all. Win+D is a hotkey registered by Explorer.exe (the shell program that's responsible for showing the taskbar, desktop icons, etc.).
It simply uses RegisterHotKey and it will receive a window message when you press WIN+D and will then take care of the whole show/hide thing.
Note you can register your own WIN+x hotkeys using said function but you're not supposed to and will run into problems - unless you were replacing Explorer.exe or such.
I don't think that this is a Window-Message at all...this is most likely handled by the kernel itself.
"Windows+D" is a hotkey combination.
Perhaps you can catch it as a WM_HOTKEY message.
You can register your own hotkeys, if you want, with the RegisterHotKey function.
Windows+D is a system wide hotkey and is reserved for use by operating system.
Hotkeys with MOD_WIN can not be registered by RegisterHotKey API or received by WM_HOTKEY message

How to programmatically detect a system hotkey?

I'm looking for a way to programmatically detect hotkeys in the system. My app supports configurable hotkeys to do different things, and I'd like to be able to tell if another app has snagged one already or it's a built-in Windows hotkey (like Win-L to lock the workstation).
And if it is another app that owns the hotkey, I'd like to be able to show that to the user. At least the name of the exe.
I'm aware of three ways to do hotkeys:
System hook using standard API's
Using the hotkey feature in the properties dialog for a shortcut
Polling async key state and responding
I doubt I can detect the third type, but what about the other two? And are there any other situations I need to know about?
I can think of three ways to do it with Standard API:
RegisterHotkey
SetWindowsHookEx(WH_KEYBOARD)
SetWindowsHookEx(WH_LL_KEYBOARD)
With the first approach, you will get in the return value whether another application already registered the very same hotkey (or whether a shortcut uses this hotkey, or Explorer.exe registered the hotkey because it is Win+E or win+R). You don't get the application name this way, though.
Using Windows Hooks or async key states for "hotkeys": I don't think it is possible to detect hotkeys there, since you might use hotkeys in a context (like replace "t" by "irst" if the last four keystrokes were "Fris") that way. You could inject the hotkey using keybd_event (with your window focused) and test if the event "gets through"; on the other hands, some cases of "hotkeys" that are implemented via hooks do not consume the keystroke so it will still get through.
The approach I would use: First make sure that for entering a shortcut, you have to type that exact shortcut into your shortcut box (if that fails, the user will see which application uses it). Then use RegisterHotkey, so you will notice (in future sessions) if another "well-behaving" application tried to steal this shortcut from you.

Reenable (windows)keys after another program has disabled it

Quake3 has disabled the alt and windows keys.
Is there any way to reenable them even while quake3 is running? I need those keys even while I have the game open.
They way I think it works is that the game registers a hotkey using RegisterHotKey and then sets the handled property to true every time the key is pressed.
So if you use UnRegisterHotkey on these keys on the quake3-window I guess the keys will start working again. The problem is that you have no idea what hotkey-id the disabled keys have.
Is there any way to enumerate the hotkeys that a window has registered to get all the hotkey-ids?
It's quite likely that Quake3 doesn't bother with RegisterHotKey at all, but instead uses DirectInput. In that case, it quite likely holds the keyboard in exclusive mode, which explains why the Windows key doesn't work - it's the OS which disables it. Quoting MSDN : "In exclusive mode, the Windows logo key is always disabled."

Resources