The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code
3 Code Libraries &nbsp

NOTE: this code has been superceded by the version at the new site.


Creating and Responding to Hotkeys

Very Simple MouseLeave Demonstration

Download the RetHotKey class and basic sample (21kb)

Download the (very foolish) demonstration project (35kb)

&nbsp Before you Begin &nbsp
&nbsp This project requires the SSubTmr.DLL component. Make sure you have loaded and registered this before trying the project. &nbsp

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:

  1. Application activation HotKeys
    These are the simplest type. When the HotKey is selected your application is activated. They are very simple to set up but they only activate your application - you can't determine if this was due to the HotKey being pressed nor take any other action.
  2. Registered HotKeys
    This type of HotKey sends a WM_HOTKEY message to your application when the HotKey is pressed. so you can choose how to respond to the key. Setting up this type is slightly more complex and you have to subclass your application's form to intercept the HotKey messages.
This article describes how to create and respond to the second type, Registered HotKeys. If you want to create a simple activation HotKey, this information is described in the HotKey Control sample. This also provides an implementation of the Common Controls HotKey control which you can use in an application to make it easier for a user to set-up HotKeys.

Registering a HotKey
Registering a system-wide HotKey is achieved in two steps:
  1. Creating a globally unique identifier for the HotKey. You do this using the Win32 Global Atom database.
  2. Registering the HotKey itself.
1. The Win32 Atom Databases
Win32 Atom databases store a list of unique strings which are internally identified by an 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 VB 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 class supplied with the demonstration project the string is created by specifying a local key string to which the executable name and the current GetTickCount value are 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 VB the VBRUN library enumeration KeyCodeConstants 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 subclassing the WM_HOTKEY message sent to the window. The 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.

Tip Extract HiWords and LoWords from a Long value
This is easy to do using the And operator and emulating a Right Shift by dividing:

LoWord = (Value And &HFFFF&)
HiWord = (Value \ &H10000) And &HFFFF&

There is a problem with this techique you have to be aware of if the HiWord of the Value has its highest bit set. In VB, there is no way of defining an Long variable as "Unsigned", so the high bit of a Long is used to identify whether the number is positive or negative. If the Value has the high bit set, then the result of the HiWord comparison above will be wrong (for example, if Value was &HFFFFFFFF, which VB interprets as -1, then the HiWord method above will yield 0!). To work around this problem, rewrite HiWord like this:

' Check for high bit (sign flag):
If (Value And &H80000000) = &H80000000 Then
' Strip it out whilst shifting then add it back in again afterwards:
HiWord = (((Value And &H7FFFFFFF)\&H10000) Or &H8000) And &HFFFF&
' Standard shift method:
HiWord = (Value \ &H10000) And &HFFFF&
End If

In Use
The cRegHotKey class supplied in the download wraps up all of this functionality into a simple class which you can drop into a project. Using the class you do this:

  1. Declare a WithEvents instance of the class in your project:

Private WithEvents m_cHK As cRegHotKey

  • Create an instance of the class and tell it your form's window handle:

  • Set m_cHK = New cRegHotKey>
    m_cHK.Attach Me.hwnd

  • Add a HotKey (or as many as you like!):

  • ' This registers CTRL-ALT-C as "MyHotKey"
    m_cHK.RegisterKey "MyHotKey", vbKeyC, MOD_CONTROL Or MOD_ALT

  • Respond to the keypress throught HotKeyPress event

  • Private Sub m_cHK_HotKeyPress(ByVal sName As String, _
    ByVal eModifiers As EHKModifiers, _
    ByVal eKey As KeyCodeConstants _
    If (sName = "MyHotKey") Then
    ' Do your processing here!
    End If

    End Sub

    The alternative download implements a couple of entirely pointless uses of the class. Firstly CTRL-ALT-C will start and stop a small earthquake on your system. Secondly, CTRL-ALT-X will attempt to kill with prejustice any instances of the supremely smug Microsoft Assistant thingy it finds on the screen. On a more useful note, it also demonstrates using the HotKey control to set up the keys on the screen (this control is included compiled into the source code).

    TopBack to top
    Source Code - What We're About!Back to Source Code


    AboutContributeSend FeedbackPrivacy

    Copyright 1998-1999, Steve McMahon ( All Rights Reserved.
    Last updated: 27 January 1999