How to programmatically detect a system hotkey? - windows

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.

Related

Why does RegisterHotKey succeed with Ctrl-C?

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().

overriding system-wide (Windows) key shortcuts in Qt app

Ctrl+Escape is a global Windows shortcut for opening main system menu. But I would like my Qt application to use this shortcut without triggering Windows main menu. I know it is probably a bad idea to override system shortcuts in general, but I would like to use this shortcut is a very limited use case.
This usecase is as follows. I have a popup window containing several rows or items. This window is opened by Ctrl+Tab and while the user holds Ctrl and keep pressing Tab, the current rows are cycled through. When the user releases Ctrl, the current row is used for some operation... But sometimes it happens that user presses Ctrl+Tab and then realizes he does not want to continue. He usually presses Escape while still holding Ctrl. And then it triggers Windows system menu and normal user gets confused, choleric user get angry... which is a bad thing. In other words I would like to be able to close the popup window when user presses Ctrl+Escape. How to do that? It is even possible?
If I write the code using this shortcut like any other short, it does not work and it always triggers Windows main menu.
As I understand it, Qt will typically not receive the key event if the underlying window system has intercepted it. For example even QtCreator cannot override system-wide shortcuts.
This question is almost a duplicate of: C++/Qt Global Hotkeys
While that question is asking specifically to capture shortcuts in a hidden/background application, I think the basic concept is the same -- capture shortcuts before the window system processes them.
From that answer, UGlobalHotkey seems pretty good, and the How to use System-Wide Hotkeys in your Qt application blog post could be useful for your limited-use case (but read the comments on that blog post about fixing the example).
Also found:
https://github.com/mitei/qglobalshortcut
https://github.com/Skycoder42/QHotkey (looks like a more detailed version of above)

Global list of assigned keyboard shortcuts osx?

I favor keyboard shortcuts over mouse actions so I'm heavily using keyboard shortcuts with all kinds of applications. Every now and then I'm running into a situation where I assign a keyboard shortcut that has already been used in a different app. Not all apps show warnings when you re-use a combination that has already been used.
Also, since I tend to forget some of the lesser used combinations, it would be nice to find out what has been assigned where.
System Preferences doesn't list all of them, but since my Mac responds to them, there must be some way to get a global list of all assigned keyboard shortcuts.
Does anyone know of a command/script/application that displays them all?
What you want may not be possible. Consider the method by which a application specific system-wide shortcuts may be implemented: event taps. An application can do whatever it wants with an event and never actually register the event with the system. Thus, no application could be written to identify every possible event!
Here is an app that does almost what you want:
http://www.ergonis.com/products/keycue/
It even updates its list when shortcuts are changed.
You can download a list of additional system-wide shortcuts from their site that includes keys not listed anywhere else. But it doesn't show shortcuts for continuously active applications such as Evernote.
Further, you can query and modify hotkeys programmatically:
http://www.theregister.co.uk/2009/02/24/hotkeys_framework2/
(but it still won't know about event taps)
This list of all system shortcuts from Apple is also useful:
http://support.apple.com/kb/HT1343

is there a winapi call or keyboard shortcut to enter windows console into "mark" mode?

Normally user is doing it by clicking right-mouse into console title bar then selecting "edit" and finally "mark". -> http://www.megaleecher.net/Copy_Paste_Text_Dos_Window
So is there a way of doing it from a console application either by sending a message/api call/keyboard sequence to its own window ?
If this is your own application and you want the richer behaviour and flexibility of a windows app rather than a console app, then use a windows app. Otherwise, you can try to automate the steps by simulating the input via SendInput. I would advise against doing this because it requires two steps (once for right-click, once to select 'Mark'). This means if someone clicks something else between these two events, your sequence will be broken. Furthermore you are really relying on the automation of an implementation detail which is prone to change at any point.
Looking through the Console Functions, it doesn't appear as though anything exists for setting the selection. The closest is going the other way with GetConsoleSelectionInfo.
If you want to process the information that is within a console application, a better alternative is to pipe it to your own process and deal with it there.
Found: PostMessage(GetConsoleWindow(), WM_COMMAND, 65522, 0);

Window hooks and applications

Related to my question here, is it possible to create a window hook that will monitor if an application has been opened or not?
Most that I have found about hooks seem to focus on user input (keyboard press, mouse events), but I could not confirm if it is possible to know that the "double click" the user made is to open an application, or just to highlight a word.
Thank you.
Indeed, window hooks would not be sufficient. In fact for the task you are asking about you could use various strategies, such as:
enumerating the processes to find the one you're looking for (Tool Help API or PSAPI)
enumerating the top-level windows on the desktop (but you're limited to your desktop then)
check for a global or local event, mutex (or other kernel object) to deduce from that that some instance of the application is running
... or even from kernel PsSetCreateProcessNotifyRoutine
probably there are variations on the above plus some more.
In essence the question is whether you want to check for the process or for some other indicator that signifies whether the program you want to check for has been started.

Resources