How can I capture a global Win+* hotkey?

4k Views Asked by At

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.

2

There are 2 best solutions below

12
On BEST ANSWER

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);
}
3
On

Even though the above solution seems to work for some people. It did not work for me. The only way to get the WIN key working was by disabling it in the registry.

https://msdn.microsoft.com/en-us/library/bb521407(v=winembedded.51).aspx

The downside: all WIN hotkeys are disabled.

There are two possible ways on doing this in the Registry:

(1) Systemwide: (I have not tested this one) HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ Keyboard Layout, Name: "Scancode Map", Type: REG_BINARY (Binary Value), Value Data: "00 00 00 00 00 00 00 00 03 00 00 00 00 00 5B E0 00 00 5C E0 00 00 00 00"

(2) For each user: (This is what I used) HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer, Name: "NoWinKeys", Data Type: REG_DWORD (DWORD Value), Value Data: 0 to disable restriction, or 1 to enable restriction