registerhotkey (user32)
Last changed: -86.11.174.174

.
Summary

C# Signature:

/// <summary> The RegisterHotKey function defines a system-wide hot key </summary>
/// <param name="hwnd">Handle to the window that will receive WM_HOTKEY messages
/// generated by the hot key.</param>
/// <param name="id">Specifies the identifier of the hot key.</param>
/// <param name="fsModifiers">Specifies keys that must be pressed in combination with the key
/// specified by the 'vk' parameter in order to generate the WM_HOTKEY message.</param>
/// <param name="vk">Specifies the virtual-key code of the hot key</param>
/// <returns><c>true</c> if the function succeeds, otherwise <c>false</c></returns>
/// <seealso cref="http://msdn.microsoft.com/en-us/library/ms646309(VS.85).aspx"/>
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers,
   uint vk);

VB Signature:

Public Declare Function RegisterHotKey Lib "user32" Alias "RegisterHotKey" (ByVal hwnd As Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long

VB.net Signature:

Declare Auto Function registerhotkey Lib "user32.dll" (Byval handle As IntPtr, ByVal id As Integer, ByVal fsModifier As Integer, ByVal vk As Integer) As Integer

User-Defined Types:

None.

Notes:

None.

Tips & Tricks:

Please add some!

Sample Code:

    // c#
    public class WindowsShell
    {
        #region fields
        public static int MOD_ALT = 0x1;
        public static int MOD_CONTROL = 0x2;
        public static int MOD_SHIFT = 0x4;
        public static int MOD_WIN = 0x8;
        public static int WM_HOTKEY = 0x312;
        #endregion

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

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

        private static int keyId;
        public static void RegisterHotKey(Form f, Keys key)
        {
            int modifiers = 0;

            if ((key & Keys.Alt) == Keys.Alt)
                modifiers = modifiers | WindowsShell.MOD_ALT;

            if ((key & Keys.Control) == Keys.Control)
                modifiers = modifiers | WindowsShell.MOD_CONTROL;

            if ((key & Keys.Shift) == Keys.Shift)
                modifiers = modifiers | WindowsShell.MOD_SHIFT;

            Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;

            Func ff = delegate()
                {
                    keyId = f.GetHashCode(); // this should be a key unique ID, modify this if you want more than one hotkey
                    RegisterHotKey((IntPtr)f.Handle, keyId, modifiers, (int)k);
                };

            f.Invoke(ff); // this should be checked if we really need it (InvokeRequired), but it's faster this way
        }

        private delegate void Func();

        public static void UnregisterHotKey(Form f)
        {
            try
            {
                Func ff = delegate()
                {
                    UnregisterHotKey(f.Handle, keyId); // modify this if you want more than one hotkey
                };

                f.Invoke(ff); // this should be checked if we really need it (InvokeRequired), but it's faster this way
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
        }
    }

    public partial class Form1 : Form, IDisposable
    {
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Keys k = Keys.A | Keys.Control;
            WindowsShell.RegisterHotKey(this, k);
        }

        // CF Note: The WndProc is not present in the Compact Framework (as of vers. 3.5)! please derive from the MessageWindow class in order to handle WM_HOTKEY
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);

            if (m.Msg == WindowsShell.WM_HOTKEY)
                this.Visible = !this.Visible;
        }

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

Sample Code:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

/// <summary> This class allows you to manage a hotkey </summary>
public class GlobalHotkeys : IDisposable
{
    [DllImport( "user32", SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    public static extern bool RegisterHotKey (IntPtr hwnd, int id, int fsModifiers, int vk);
    [DllImport( "user32", SetLastError = true )]
    public static extern int UnregisterHotKey (IntPtr hwnd, int id);
    [DllImport( "kernel32", SetLastError = true )]
    public static extern short GlobalAddAtom (string lpString);
    [DllImport( "kernel32", SetLastError = true )]
    public static extern short GlobalDeleteAtom (short nAtom);

    public const int MOD_ALT = 1;
    public const int MOD_CONTROL = 2;
    public const int MOD_SHIFT = 4;
    public const int MOD_WIN = 8;

    public const int WM_HOTKEY = 0x312;

    public GlobalHotkeys () {
    this.Handle = Process.GetCurrentProcess().Handle;
    }

    /// <summary> handle of the current process </summary>
    public IntPtr Handle;

    /// <summary> the ID for the hotkey </summary>
    public short HotkeyID {
    get;
    private set;
    }

    /// <summary> register the hotkey </summary>
    public void RegisterGlobalHotKey (int hotkey, int modifiers, IntPtr handle) {
    UnregisterGlobalHotKey();
    this.Handle = handle;
    RegisterGlobalHotKey( hotkey, modifiers );
    }

    /// <summary> register the hotkey </summary>
    public void RegisterGlobalHotKey (int hotkey, int modifiers) {
    UnregisterGlobalHotKey();

    try {
        // use the GlobalAddAtom API to get a unique ID (as suggested by MSDN docs)
        string atomName = Thread.CurrentThread.ManagedThreadId.ToString( "X8" ) + this.GetType().FullName;
        HotkeyID = GlobalAddAtom( atomName );
        if ( HotkeyID == 0 )
        throw new Exception( "Unable to generate unique hotkey ID. Error: " + Marshal.GetLastWin32Error().ToString() );

        // register the hotkey, throw if any error
        if ( !RegisterHotKey( this.Handle, HotkeyID, modifiers, (int) hotkey ) )
        throw new Exception( "Unable to register hotkey. Error: " + Marshal.GetLastWin32Error().ToString() );

    } catch ( Exception e ) {
        // clean up if hotkey registration failed
        UnregisterGlobalHotKey();
        Console.WriteLine( e );
    }
    }

    /// <summary> unregister the hotkey </summary>
    public void UnregisterGlobalHotKey () {
    if ( this.HotkeyID != 0 ) {
        UnregisterHotKey( this.Handle, HotkeyID );
        // clean up the atom list
        GlobalDeleteAtom( HotkeyID );
        HotkeyID = 0;
    }
    }

    public void Dispose () {
    UnregisterGlobalHotKey();
    }
}

How to use :

GlobalHotkeys hotkey;


hotkey = new GlobalHotkeys();
hotkey.RegisterGlobalHotKey( (int) Keys.F11, GlobalHotkeys.MOD_CONTROL );
hotkey.UnregisterGlobalHotKey();

protected override void WndProc (ref Message m) {
     const int WM_HOTKEY = 0x0312;

     switch ( m.Msg ) {
     case WM_HOTKEY:
         if ( (short) m.WParam == hotkey.HotkeyID ) {
         // do your thing
         }
         break;
     default:
         base.WndProc( ref m );
         break;
     }
}

Alternative Managed API:

The ManagedWindowsApi project (http://mwinapi.sourceforge.net) provides a

Hotkey class to register global hotkeys.

Documentation