Search code examples
c#keyboard-shortcutswindows-key

How can I capture a global Win+* hotkey?


I know there are a lot of resources already on how to capture a global hotkey with C# (using Ctrl, Alt, or whatever else), but I haven't seen any that work with the Windows key.

Is it possible to have a program capture and respond to a Win+* global keyboard shortcut? For example, show a form if the user presses Win+Z or something like that.


Solution

  • The Windows keys can be used as any other modifier (const int MOD_WIN = 0x0008 according to MSDN). I have tested this with a RegisterHotKey-based code and works fine.

    UPDATE

    Sample code showing how to hook different combinations of keys including the Windows keys by relying on RegisterHotKey (LParam values collected manually):

    [System.Runtime.InteropServices.DllImport("User32")] public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
    [System.Runtime.InteropServices.DllImport("User32")] public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
    public const int MOD_SHIFT = 0x4;
    public const int MOD_CONTROL = 0x2;
    public const int MOD_ALT = 0x1;
    public const int WM_HOTKEY = 0x312;
    public const int MOD_WIN = 0x0008;
    
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_HOTKEY && m.WParam == (IntPtr)0)
        {
            IntPtr lParamWINZ = (IntPtr)5898248;
            IntPtr lParamWINCTRLA = (IntPtr)4259850;
            if (m.LParam == lParamWINZ)
            {
                MessageBox.Show("WIN+Z was pressed");
            }
            else if (m.LParam == lParamWINCTRLA)
            {
                MessageBox.Show("WIN+CTRL+A was pressed");
            }
        }
        base.WndProc(ref m);
    }
    
    private void Form1_Load(object sender, EventArgs e)
    {
        this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
    
        RegisterHotKey(this.Handle, 0, MOD_WIN, (int)Keys.Z);
        RegisterHotKey(this.Handle, 0, MOD_WIN + MOD_CONTROL, (int)Keys.A);
    }
    
    private void Form1_FormClosing(Object sender, FormClosingEventArgs e)
    {
        UnregisterHotKey(this.Handle, 0);
    }