HotKey – Global shortcuts

 
 
  • Gérald Barré

Hotkeys let you associate a key combination with an action. For example, Alt+F4 closes the current application; this shortcut is handled by Windows, not by individual applications. I needed the same functionality in my WindowManager application, which runs in the background and responds to key combinations to move the current window.

As you might expect, this feature requires some interop. Here are the two functions used:

C#
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, ModifierKeys modifiers, Keys keys);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

[Flags]
public enum Modifiers
{
    None = 0x0000,
    Alt = 0x0001,
    Ctrl = 0x0002,
    Shift = 0x0004,
    Win = 0x0008
}
  • hWnd corresponds to the handle of the window:
    • WinForm : myWindow.Handle
    • WPF : new WindowInteropHelper(myWindow).Handle
  • id is a number that identifies which hotkey was triggered
  • ModifierKeys matches keys Control, Alt, Shift and Windows.
  • Keys matches all other keys. In WPF, you must add a reference to System.Windows.Forms or recreate the enumeration.

You can declare a shortcut using RegisterHotKey:

C#
RegisterHotKey(Handle, id: 1, ModifierKeys.Control, Keys.A);
RegisterHotKey(Handle, id: 2, ModifierKeys.Control | ModifierKeys.Alt, Keys.B);

Now that the hotkeys are registered, they must be associated with a handler. To do this, hook into the Windows message loop:

C#
ComponentDispatcher.ThreadPreprocessMessage += ThreadPreprocessMessageMethod;
C#
private void ThreadPreprocessMessageMethod(ref MSG msg, ref bool handled)
{
    const int WmHotKey = 786;
    if (handled || msg.message != WmHotKey)
        return;

    var id = (int)msg.wParam;
    if (id == 1) // Ctrl + A
    {
        // TODO
        handled = true;
    }
    else if (id == 2) // Ctrl + Alt + B
    {
        // TODO
        handled = true;
    }
}

The only thing left to do is to unregister the shortcut when closing the application:

C#
UnregisterHotKey(Handle, id: 1);

All the code is available in the application WindowManager.

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?