BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Input / Output
.NET 1.1+

Registering System-Wide Hot Keys

Some Windows applications execute in the background and are activated only as required. To enhance such a program's usability it is useful to register a system-wide hot key. This allows the software to activate when a specific key combination is pressed.

Unregistering the Hot Key

It is important that any registered hot keys are unregistered when they are no longer required. For the sample, we will unregister the hot key in the FormClosing event. Add this event to the project and include the following code:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    MessageBox.Show(UnregisterHotKey((IntPtr)Handle, 1).ToString());
}

Capturing the Hot Key Message

When the user presses the hot key, a message is sent to the window that was specified in the call to RegisterHotKey. In the sample code, the window is the only form in the project. To receive the message, you must override a method of the form. This method, named "WndProc", is used to receive all messages that are destined for the window.

The WndProc method defines a single parameter that contains the received message. This is encapsulated in an instance of the Message class from the System.Windows.Forms namespace. As the method receives many messages that are not related to registered hot keys, we must check that the type of any received message is correct. This is achieved by comparing the Msg property of the message to the WM_HOTKEY constant that was declared earlier. If they match, an appropriate action can be taken. Non-matching messages must not be lost so these are processed with a call to the base class's method.

To override the method, add the following code to the form's class. This changes the size of the form by setting the normal window state and activates the form to ready it for potential input.

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if (m.Msg == WM_HOTKEY)
    {
        WindowState = FormWindowState.Normal;
        Activate();
    }
}

With the WndProc method overridden, execute the program. Try switching to another program or minimising the form before pressing the Windows key and Q simultaneously to see the form reappear and become active.

Adding a Second Hot Key

Sometimes you will want to register more than one hot key for a single form. To extend the sample code, we will add a second hot key, this time a combination of the Windows key, Alt and Q. The two modifier constants will be combined using the OR operator and a different unique identifier will be used.

To register the second hot key, modify the Load event as follows:

private void Form1_Load(object sender, EventArgs e)
{
    MessageBox.Show(RegisterHotKey((IntPtr)Handle, 1, MOD_WIN, (int)Keys.Q).ToString());
    MessageBox.Show(
        RegisterHotKey((IntPtr)Handle, 2, MOD_WIN | MOD_ALT, (int)Keys.Q).ToString());
}

As we are registering two hot keys, we should also unregister both combinations. Modify the FormClosing event as follows:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    MessageBox.Show(UnregisterHotKey((IntPtr)Handle, 1).ToString());
    MessageBox.Show(UnregisterHotKey((IntPtr)Handle, 2).ToString());
}

Finally we will modify the overridden WndProc method to change the behaviour according to the hot key pressed. The behaviour of the original hot key will be unchanged. When the additional hot key is used, we will display and activate the form as before and will also display a message box.

To differentiate between the messages for the two hot keys we can read the message's WParam property. When a WM_HOTKEY message is received, the WParam property will contain the unique ID assigned to the hot key during registration. We can therefore check if this property is set to 2 and display a message box only when it is.

Modify the code for the WndProc method as follows and run the program again to test the new behaviour:

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if (m.Msg == WM_HOTKEY)
    {
        WindowState = FormWindowState.Normal;
        Activate();
        if (m.WParam.ToInt32() == 2) MessageBox.Show("Hot Key!");
    }
}
14 June 2009