Monday, May 28, 2012

Create Global Hotkeys

This topic is about creating global hotkeys for a C# application. Once registered, the hotkeys are active system wide - meaining: Also when another program is active at the moment, the pressing of the hotkey is still made known to our application. This way, for example a running inactive application can be called to the front.
We define a hotkey with the API function RegisterHotKey(). This expects 4 parameters:

  • The handle of the window, which is supposed to get the message.
  • The ID of the hotkey, important when multiple hotkeys are registered per application. If NULL is handed over, the hotkey is just registered as the only hotkey for the application.
  • The control keys, which have to be pressed for activating the hotkey (e.g. Alt, Ctrl ...).
  • The key, which has to be pressed for activating the hotkey (e.g. "X").
Analogously to that there exists the function UnregisterHotKey(), which expects the window handle and ID of the hotkey, with which the function can be deleted (for example at the termination of the program).
When the hotkey is pressed, the application gets the message WM_HOTKEY. To receive this, the function WndProc() has to be overridden.
The following sample code creates 2 hotkeys (Shift + Ctrl + X and Shift + Ctrl + Y), I think the method should become clear this way:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);

        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        const int MOD_CONTROL = 0x0002;
        const int MOD_SHIFT = 0x0004;
        const int WM_HOTKEY = 0x0312;

        private void Form1_Load(object sender, EventArgs e)
        {
            RegisterHotKey(this.Handle, 1, MOD_CONTROL + MOD_SHIFT, (int)Keys.X);
            RegisterHotKey(this.Handle, 2, MOD_CONTROL + MOD_SHIFT, (int)Keys.Y);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnregisterHotKey(this.Handle, 1);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_HOTKEY && (int)m.WParam == 1)
                MessageBox.Show("Hotkey X pressed.");
            if (m.Msg == WM_HOTKEY && (int)m.WParam == 2)
                MessageBox.Show("Hotkey Y pressed.");
            base.WndProc(ref m);
        }

    }
}


Further information can be found in the MSDN.

2 comments:

  1. Why Did you this.handle in RegisterHotkey

    ReplyDelete
    Replies
    1. what is the purpose of this.handle?

      Delete