Click here to Skip to main content
Click here to Skip to main content

Beginner's Tutorial - Using global hotkeys

By , 28 Apr 2002
 

Introduction

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.

BOOL RegisterHotKey(
    HWND hWnd,         // window to receive hot-key notification
    int id,            // identifier of hot key
    UINT fsModifiers,  // key-modifier flags
    UINT vk            // virtual-key code
);

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 return TRUE. So please do not fail to check the return value.

Un-registering hotkeys

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 :-

BOOL UnregisterHotKey(
    HWND hWnd,  // window associated with hot key
    int id      // identifier of hot key
);

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.

UnregisterHotKey(hWndMain,300);

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 wParam 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.

ON_MESSAGE(WM_HOTKEY,OnHotKey)

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 WM_HOTKEY message.

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.

Sample Program

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.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

About the Author

Nish Sivakumar
United States United States
Member
Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.
 
Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com.
 
Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy Summer Love and Some more Cricket as well as a programming book – Extending MFC applications with the .NET Framework.
 
Nish's latest book C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.
 
Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberMember 96348733 Dec '12 - 18:28 
nice work to go through,as am a beginner need still basic coding
QuestionDownload linkmembersubheesh23 Aug '11 - 17:27 
Not Getting Downloaded this Source
AnswerRe: Download linkmvpNishant Sivakumar24 Aug '11 - 11:32 
Worked for me just now. Try again please. Thanks
Regards,
Nish
My technology blog: voidnish.wordpress.com

Question.net hotkeysmembertsdaemon29 Jun '11 - 1:03 
Got some little question, how can I do something like this with .net C#?
GeneralMy vote of 5membersamq17 Nov '10 - 2:15 
simple in reading ....and great to read ....
 
pAwAn Singh
Generalbad word filter to protect my kids.memberZUPERKOOL7 Feb '10 - 6:48 
a warm hello to all msn gurus Smile | :)
 
hi i am trying to develop a badword filter for msn/messenger to help protect my kids from bad words... "yes those words ...that later i we have to make up a fake definition when they ask dad what is the meaning of f**k :x"
 
anyways, i started using winpcap to capture the incoming socket but later found out that since sp2 xp will not allowed this"
 
the big question:
 
while reading this article it came to my attention that maybe i could filter at the application level....
 
do you think if taking this/your aproche would eventually end up in a simple badword_filter.dll.
 
thanks
 

Ivo Gomez
http://ivogomez.com
 
<br><br>
GeneralGetting a compilation errormemberNitsanBr31 Aug '08 - 7:36 
I tried to compile the basic project shown here, and I'm getting an error. Here's the log:
 
1>------ Build started: Project: HotKeyTest, Configuration: Debug Win32 ------
1>Compiling...
1>StdAfx.cpp
1>c:\users\nitsan\desktop\globalhksnew\stdafx.h(15) : fatal error C1083: Cannot open include file: 'afxwin.h': No such file or directory
1>Build log was saved at "file://c:\Users\Nitsan\Desktop\globalhksnew\Debug\BuildLog.htm"
1>HotKeyTest - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
 
I'm using VC++ 2008.
Help?
GeneralQuery on RegisterHotKeymemberMember 407504817 Jul '08 - 19:44 
Hi,
 
I would to create hotkey for my simple window form programs written in Visual C++. I try to defined to hotkey as F1 - F12 but it fails. I've set the hotkey as follows:

RegisterHotKey(hWnd,101,0,VK_F7)
 
Can i defined the hotkey with F1 - F12 without having any combination of other key? Kindly advise.
 
Thanks.
 
Yours sincerely,
Sheauchee
GeneralRe: Query on RegisterHotKeymemberzapaaris18 Aug '11 - 9:51 
The F12 key is reserved for use by the debugger at all times, so it should not be registered as a hot key. Even when you are not debugging an application, F12 is reserved in case a kernel-mode debugger or a just-in-time debugger is resident.
Follow the link
http://msdn.microsoft.com/en-us/library/ms646309.aspx
GeneralHotKey for IEmemberlal001217 Jun '08 - 22:10 
Hai all plzz any one help me... Itzz urgent.I created a plugin for IE in VC6 using IDeskband.But dont Know how to launch that plugin with a hot key like ALT+l.
Questionhow to trap Hotkey without using Massage Map in win32 app?memberrajksingh4 May '08 - 20:28 
how to trap Hotkey without using Massage Map in win32 app?
GeneralThanks -memberbruccutler31 Jan '08 - 7:19 
I looked all over the MSDN site for an example. I found exactly what I needed here.
 
Thanks - all these years later.
GeneralMinor correction -memberSabuncu14 Aug '07 - 8:12 
Very helpful article. Just a minor correction; the article says:
 
"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."
 
But the code supplied w/ the article does not check wParam, which is OK since there is only one hot key being handled; that is, there is no possibility that OnHotKey() will be called with anything else but that specific hot key. Had there been the possibility of registering multiple hot keys, then wParam would have to be checked.
 
Thanks -
 
Todd
GeneralThanksmemberHakunaMatada15 May '07 - 19:26 
Geez, thanks a lot Nish. You rock!
 
---
Beer | [beer] Hakuna-Matada Beer | [beer]
It means no worries for the rest of your days...
It's our problem free, Philosophy

Jig | [Dance]
 
"I think my response was 'What idiot dreamed this up?'" -- Mary Ann Davidson, Oracle's chief security officer, in typical blunt manner, remembering her reaction to the company's scheme to brand its databases as "unbreakable."

Questionhow to remap keyboard globallymembertedkidane11 May '07 - 5:57 
how to remap keyboard globally using unicode charater for example when i press a it displays 0x1200 character on any editor like notpade msword and other tanck u
 
tewodros

Question? FocusmemberSynetech22 Jul '06 - 18:25 
Hi,
 
Does anyone know an easy way to set the focus and display the dialog app/messagebox when the hotkey is pressed?
 
I've set up an MFC dialog app that captures a global hotkey and displays a simple messagebox. However if another window is covering up the dialog when the hotkey is pressed, the messagebox is not seen.
 
Any ideas?
 
--
Synetech

QuestionHow to make this example to work with Visual C++2005?memberhires7725 Jun '06 - 4:18 
Well, read the subject.
This article is quite old, I think i needs some upgrade cause there are no good guides for newbies how to register hot keys.
QuestionHow to Use F1...F12 and other Virtual keys as a Hotkey !! plzzz helpmemberManni Singh7 Jun '06 - 9:28 
i want to Register F1...F12 and other Virtual keys as a Globally hot key . plz tell me how can i do tht.. plzz
AnswerRe: How to Use F1...F12 and other Virtual keys as a Hotkey !! plzzz helpmemberSynetech4 May '08 - 9:22 
A little late for Manni, but for future readers and passersby, use VK_F1…VK_F12 for vk.
 
--
Synetech

GeneralgOoDmemberLivingThoughts11 Feb '06 - 18:17 
rEaLlY nIcE.
kEeP iT uP.Big Grin | :-D
QuestionIs there anyway to handle HOTKEY messages like "Control + Alt + Delete" in one's application?memberSstar7 Feb '06 - 15:31 
Hi, Nish,
 
Nice article. Simple and clear.
 
Would there be anyway to handle the system Hotkey messages like "Control" + "Alt" + "Delete" in one's application? I have tried to register an Hot Key with the following parameters
 
fsModifier = MOD_CONTROL + MOD_ALT;
vk = VK_DELETE;
 
The registration always fails.
But if I try to register "Alt" + "Tab", i.e.
fsModifier = MOD_ALT;
vk = VK_TAB;
 
The registraton would succeed. What is the moral behind this fact? Do you have any idea about how to handle "Control" + "Alt" + "Delete" as well?
 
Eric CH
AnswerRe: Is there anyway to handle HOTKEY messages like "Control + Alt + Delete" in one's application?memberLivingThoughts14 Feb '06 - 20:16 
If i am not mistaken CTRL+ALT+DEL is a special key combination. you have to use system wide keyboard hooks.
 

۞It is on our failures that we base a new and different and better success.


Generalctrl+alt+del is reserved for operating system usemembercwb31065 Sep '08 - 9:35 
FWIW, LivingThoughts is correct that ctrl+alt+del is reserved for operating system use. Windows NT and its successors are designed to meet C2-level of security (as defined in the US Department of Defense's "Orange Book"). One of the features required by C2 is that there be a "trusted path" between the user and the operating system for such actions as logging on. The reason is to prevent a fake logon program running and stealing user's passwords. Microsoft chose to use the keyboard chord of ctrl+alt+del to invoke the "trusted path". That's why it is difficult to reassign this chord.
GeneralRe: ctrl+alt+del is reserved for operating system usememberguocang18 Sep '08 - 7:41 
How to handle the Ctrl+C (Copy) event without using the WndPro way?
(using C# is prefered).
 
Thanks.
QuestionHow to trap F8 key for specified exe?memberdkdsnaidu14 Jul '05 - 19:41 
HI,
I am developing ATL COM Addin for MS Word. I want trap F8 key. It will work for only MS Word. How can I solve this problem with "RegisterHotKey"? Now, I am using SetWindowHookEx(WH_KEYBOARD,....). Shall we solve this problem with RegisterHotKey API?
 
Thanks in advance.
 
Regards,
Dkds.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 29 Apr 2002
Article Copyright 2002 by Nish Sivakumar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid