Extending the .NET Windows Forms to respond to System Wide HotKeys
One of the Windows API features which isn't included in the .NET Framework is setting up and receiving notifications from system-wide HotKeys. This article presents an extended version of System.Windows.Forms.Form which adds HotKey functionality.
HotKeys in Win32
Win32 allows you to set up combinations of key-presses which can be associated with an application on a system-wide scope, called Hotkeys. When a user presses a registered HotKey it doesn't matter which application is active when they pressed it, the hot-key message will get routed to your application.
There are two types of HotKeys:
This article describes how to create and respond to the second type, Registered HotKeys.
Registering a HotKey
Registering a system-wide HotKey is achieved in two steps:
1. The Win32 Atom Databases
Win32 Atom databases store a list of unique strings which are internally identified by a 16 bit integer ID. The Global Atom database creates string lists which are accessible to all processes. In addition to this each process on the system can have its own Local Atom database. These functions could be quite useful for other purposes - if you need to store a list of unique strings and IDs in an application, you could take advantage of the Atom database to do it. However, as there is only one atom database per process you would have to be careful! Note that an applications process includes both the executable and any OCXs or DLLs being used in that executable.
The Global Atom database functions in Win32 are GlobalAddAtom, GlobalDeleteAtom, GlobalFindAtom and GlobalGetAtomName. The first step of registering a HotKey is to create a string that is unlikely to be in use by any other application on the system and then get an ID for it by calling GlobalAddAtom for that string. In the download string is created by specifying a local key string to which the current GetTickCount value is appended.
2. Registering the HotKey
Registering the key itself is acheived using Win32's unusually sensibly named RegisterHotKey function. This takes the window handle you want to send the messages to, the globally unique identifier you created using the Global Atom database, a bit flag containing the Shift, Ctrl, Alt or Windows Key keys which have to be pressed for the HotKey and the Virtual Key Code of the key you want to register. Note that in .NET the System.Windows.Forms.Keys enumeration corresponds directly to the Win32 Virtual Key Code constants. These are the key values that are passed to you in the KeyUp and KeyDown events.
Responding to HotKeys
Once you've set up a HotKey, you can respond to it by responding to the WM_HOTKEY message sent to the window by overriding a form's WndProc. The message's wParam of the WM_HOTKEY message contains the globally unique identifier you assigned to the HotKey, and the lParam contains the virtual key code in the HiWord and the key modifiers in the LoWord.
Putting it all Together
To make this easy to use, the download contains an extended version of System.Windows.Forms.Form which includes all of the functionality you need to set up and respond to hotkeys. This is stored within the HotKeyFormLib class in the namespace vbAccelerator.Components.HotKey. The implementation consists of the following classes:
To use the library, simply add the relevant version of HotKeyFormLib to your project. Then modify the form you want to respond to HotKeys to be a HotKeyForm rather than a System.Windows.Forms.Form. Now you can start adding hotkeys and responding to events.
To add a HotKey, create a new instance of the HotKey class and set the Name, KeyCode and Modifier properties. There is a constructor which enables you to do this all at one time. Then add the HotKey to the hot key collection using the HotKeys property.
Once you've added the HotKey, you will want to respond to any events. The event raised by the is called HotKeyPressed and also has a corresponding delegate called HotKeyPressedEventHandler. The event parameter to this method contains the HotKey which has been pressed.
Try The Sample
The samples provided register Ctrl+Shift+Up as a HotKey and respond to presses by bringing the application to the foreground, regardless of whether it is hidden or minimised when the hot key is pressed. Another application which uses this code is the "ZoomIn" utility, which uses it to allow you to take dynamic snapshots of screen areas regardless of whether you are clicking on a button in the application you're Zooming in on.