Today morning, someone was asking about using hot keys in the VC++ forum. I
had never used hotkeys and it intrigued me not a little. I thought I'd cook up a
simple application and write a nice little article for CP. These days I have
been writing too many .NET articles and I thought it's time I wrote a normal
unmanaged program as Mike Dunn or Colin Davies would call it.
First of all remember that hot keys are going to be global to the Operating
System. Thus be careful what you choose as your hot key. Also decide whether
your application is important enough to have an Operating System level short cut
key. The user might accidentally press Ctrl-D and suddenly find your program
popping up. In fact if it's an old enough person the sudden popping up of an
unexpected window might even give him or her a heart attack. This is obviously a
situation to be avoided.
How to set hot keys
Well, setting hot keys is just an API call away for anyone who might be
thinking it's a complicated process. We use the API call
RegisterHotKey which is prototyped as follows.
HWND hWnd, int id, UINT fsModifiers, UINT vk );
A normal application can use any value between 0x0000 and 0xBFFF but if you
are writing a DLL, then you must use
GlobalAddAtom to get a unique
identifier for your hot key. There are currently four allowed key modifiers
which let you trap the
Ctrl key, the
Alt key, the
Shift key and the
WinKey. You may trap them
individually or as combinations of each other. For example you can have a
combination short cut like Ctrl-Shift-WinKey-Y to pop up yahoo messenger, though
why you'd want to set up that kind of convoluted short cut would be a very tough
question to answer.
RegisterHotKey(hWndA, 100, MOD_ALT | MOD_SHIFT, 'P');
RegisterHotKey(hWndA, 200, MOD_WIN, 'R');
Okay, setting the hot key was simple. So, what does this do? Good question!
What we have achieved is that, whenever this hot key is pressed a
WM_HOTKEY message is send to the window specified by the
HWND parameter. Neat. Also remember that if you are trying to set a
hot key that has already been registered like the WinKey-E hot key that brings
up Explorer, this function will fail and return
FALSE, else it will
TRUE. So please do not fail to check the return value.
Well as you would expect, there is an API call called
UnregisterHotKey which un-registers our hot key or hot keys.
Remember to un-register all hot keys when your program exits. In fact just to be
safe un-register a key which might actually already have been un-registered. No
harm done at all. This function is prototyped as :-
HWND hWnd, int id );
The identifier is the same one which we had passed to
RegisterHotKey. If you had used
GlobalAddAtom to get a
unique identifier, you must save it somewhere so that you can use it to
un-register the hot key.
Handling the hot key
If you are writing a straight API program you shouldn't have too much
difficulty in handling the
WM_HOTKEY message. Just check
which will contain the identifier of the hot key. The problem with MFC is that
for some strange reason, the class wizard does not seem to include the
WM_HOTKEY message. I was using VC++ 6.0 with SP5 when i originally
wrote the program. I am not aware of
whether this is the same for VC++ 7.0 or even whether there is some kind of
obscure workaround for VC++ 6.0. If anyone knows a work around, kindly let me
know too. But there is nothing stopping us from adding the entry to the message
map. It's perfectly within the rules to do that, I say.
Okay, that was easy. Now we add our function. Just add this function to your
window class, the same window that is going to receive the
LRESULT OnHotKey(WPARAM wParam, LPARAM lParam);
Now all you have to do is to write the function body, check
wParam and see if
it is the identifier of your hot key and do what you want. Typically you might
want to use
ShellExecute to start your program, which is what I
have done in the sample program for this article.
Well. the sample program was quickly put together and it lets you choose a
single modifier key (it does not allow multiple modifiers) and you can choose a
virtual key between A and Z. You can also browse to an executable and when you
click the Start button, the hot key is alive. It's a very simple program and
does not really do much. But you can look through the source code, if my
explanations weren't coherent enough for you.