none
Assign global hotkey to a System Tray application in c#

    Question

  •  Is it possible to assign a global hotkey to an application that is running from the System Tray , The app has only one form and i never close that form(only use this.Hide() and ShowInTaskbar=false ) and what i am looking is to Show the form again from the main class once the user press some shortcuts(global hot key )

    http://social.msdn.microsoft.com/forums/en-us/clr/thread/BB49A3B0-6A1A-46BA-8755-83053B934F30

    This thread discuss the same , but the suggested answer link is broken

    htttp://www.dotnet2themax.com/ShowContent.aspx?ID=103cca7a-0323-47eb-b210-c2bb7075ba78



    Thanks ***Share Knowledge to gain more***

    Tuesday, June 05, 2012 6:56 AM

Answers

  • Hi FullPgmr,

    Please try this sample(it is simple to help you understand):

    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 WindowsFormsApplicationHotKey
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                Boolean success = Form1.RegisterHotKey(this.Handle, this.GetType().GetHashCode(), 0x0000, 0x42);//Set hotkey as 'b'
                if (success == true)
                {
                    MessageBox.Show("Success");
                }
                else
                {
                    MessageBox.Show("Error");
                }
            }
            [DllImport("user32.dll")]
            public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
            //[DllImport("user32.dll")]
            //public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == 0x0312)
                {
                    MessageBox.Show("Catched");//You can replace this statement with your desired response to the Hotkey.
                }
                base.WndProc(ref m);
            }
        }
    }
    

    Also, you can take a look at this page which I think is helpful: http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=5914

    Have a nice day.


    Alexander Sun [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Alexander Sun Tuesday, June 26, 2012 8:23 AM
    Wednesday, June 06, 2012 6:17 AM

All replies

  • You need to use Windows API to define global hotkeys.

    You can find a nice example here: http://bloggablea.wordpress.com/2007/05/01/global-hotkeys-with-net/.


    Marco Minerva [MCPD]
    Blog: http://blogs.ugidotnet.org/marcom
    Twitter: @marcominerva

    Tuesday, June 05, 2012 7:28 AM
  • public sealed class KeyboardHook : IDisposable
    {
        // Registers a hot key with Windows.
        [DllImport(“user32.dll”)]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
        // Unregisters the hot key with Windows.
        [DllImport(“user32.dll”)]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
        /// <summary>
        /// Represents the window that is used internally to get the messages.
        /// </summary>
        private class Window : NativeWindow, IDisposable
        {
            private static int WM_HOTKEY = 0×0312;
    
            public Window()
            {
                // create the handle for the window.
                this.CreateHandle(new CreateParams());
            }
    
            /// <summary>
            /// Overridden to get the notifications.
            /// </summary>
            /// <param name="m"></param>
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
    
                // check if we got a hot key pressed.
                if (m.Msg == WM_HOTKEY)
                {
                    // get the keys.
                    Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
                    ModifierKeys modifier = (ModifierKeys)((int)m.LParam & 0xFFFF);
    
                    // invoke the event to notify the parent.
                    if (KeyPressed != null)
                        KeyPressed(this, new KeyPressedEventArgs(modifier, key));
                }
            }
    
            public event EventHandler<KeyPressedEventArgs> KeyPressed;
    
            #region IDisposable Members
    
            public void Dispose()
            {
                this.DestroyHandle();
            }
    
            #endregion
        }
    
        private Window _window = new Window();
        private int _currentId;
    
        public KeyboardHook()
        {
            // register the event of the inner native window.
            _window.KeyPressed += delegate(object sender, KeyPressedEventArgs args)
            {
                if (KeyPressed != null)
                    KeyPressed(this, args);
            };
        }
    
        /// <summary>
        /// Registers a hot key in the system.
        /// </summary>
        /// <param name="modifier">The modifiers that are associated with the hot key.</param>
        /// <param name="key">The key itself that is associated with the hot key.</param>
        public void RegisterHotKey(ModifierKeys modifier, Keys key)
        {
            // increment the counter.
            _currentId = _currentId + 1;
    
            // register the hot key.
            if (!RegisterHotKey(_window.Handle, _currentId, (uint)modifier, (uint)key))
                throw new InvalidOperationException(“Couldn’t register the hot key.”);
        }
    
        /// <summary>
        /// A hot key has been pressed.
        /// </summary>
        public event EventHandler<KeyPressedEventArgs> KeyPressed;
    
        #region IDisposable Members
    
        public void Dispose()
        {
            // unregister all the registered hot keys.
            for (int i = _currentId; i > 0; i–)
            {
                UnregisterHotKey(_window.Handle, i);
            }
    
            // dispose the inner native window.
            _window.Dispose();
        }
    
        #endregion
    }
    
    /// <summary>
    /// Event Args for the event that is fired after the hot key has been pressed.
    /// </summary>
    public class KeyPressedEventArgs : EventArgs
    {
        private ModifierKeys _modifier;
        private Keys _key;
    
        internal KeyPressedEventArgs(ModifierKeys modifier, Keys key)
        {
            _modifier = modifier;
            _key = key;
        }
    
        public ModifierKeys Modifier
        {
            get { return _modifier; }
        }
    
        public Keys Key
        {
            get { return _key; }
        }
    }
    
    /// <summary>
    /// The enumeration of possible modifiers.
    /// </summary>
    [Flags]
    public enum ModifierKeys : uint
    {
        Alt = 1,
        Control = 2,
        Shift = 4,
        Win = 8
    }

    Tuesday, June 05, 2012 7:34 AM
  • How can i use this in a winform application running on System Tray

    Thanks ***Share Knowledge to gain more***

    Tuesday, June 05, 2012 8:35 AM
  • Hi FullPgmr,

    Please try this sample(it is simple to help you understand):

    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 WindowsFormsApplicationHotKey
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                Boolean success = Form1.RegisterHotKey(this.Handle, this.GetType().GetHashCode(), 0x0000, 0x42);//Set hotkey as 'b'
                if (success == true)
                {
                    MessageBox.Show("Success");
                }
                else
                {
                    MessageBox.Show("Error");
                }
            }
            [DllImport("user32.dll")]
            public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
            //[DllImport("user32.dll")]
            //public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == 0x0312)
                {
                    MessageBox.Show("Catched");//You can replace this statement with your desired response to the Hotkey.
                }
                base.WndProc(ref m);
            }
        }
    }
    

    Also, you can take a look at this page which I think is helpful: http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=5914

    Have a nice day.


    Alexander Sun [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Alexander Sun Tuesday, June 26, 2012 8:23 AM
    Wednesday, June 06, 2012 6:17 AM
  • I know I'm reviving an old thread but I spent so long working this out that I though I should share.

    All of the examples above work fine when the form is visible but when the form gets hidden and minimized to the system tray windows is unable to send the event message to the forms handle.

    You can resolve this by creating a class as a NativeWindow and refer to the classes handle.

    The below example also works for multiple global hotkeys which is another thing which took me a while to find out how to do.

    This is my code in the main form:

    using System.Runtime.InteropServices;
    
    namespace Project1
    {
        public partial class Form1: Form
        {
    
            [DllImport("user32.dll")]
            public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
            [DllImport("user32.dll")]
            public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
            
    
            public Form1()
            {
                InitializeComponent();
    
                var HotKeyManager = new HotkeyManager();
    
                //RegisterHotKey (Hangle, Hotkey Identifier, Modifiers, Key)
                RegisterHotKey(HotKeyManager.Handle, 123, Constants.ALT + Constants.SHIFT, (int)Keys.P);
                RegisterHotKey(HotKeyManager.Handle, 234, Constants.ALT + Constants.SHIFT, (int)Keys.O);
    
            }

    This is my code in the NativeWindow class:

    using System.Windows.Forms;
    
    namespace Project1
    {
    
        //This class is not required but makes managing the modifiers easier.
        public static class Constants
        {
            public const int NOMOD = 0x0000;
            public const int ALT = 0x0001;
            public const int CTRL = 0x0002;
            public const int SHIFT = 0x0004;
            public const int WIN = 0x0008;
    
            public const int WM_HOTKEY_MSG_ID = 0x0312;
        }  
    
        public sealed class HotkeyManager : NativeWindow, IDisposable
        {
            public HotkeyManager()
            {
                CreateHandle(new CreateParams());
            }
    
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == Constants.WM_HOTKEY_MSG_ID)
                {
                    if (m.WParam.ToInt32() == 123)
                    {
                        MessageBox.Show("HotKey ID: 123 has been pressed");
                    }
    
                    if (m.WParam.ToInt32() == 234)
                    {
                        MessageBox.Show("HotKey ID: 234 has been pressed");
                    }
                }
                base.WndProc(ref m);
            }
    
            public void Dispose()
            {
                DestroyHandle();
            }
    
    
        }
    
    }


    If you would like to download an example project I just put together click here: Global Hotkey from System Tray
    • Proposed as answer by Joe_DM Saturday, December 14, 2013 1:34 AM
    • Edited by Joe_DM Saturday, December 14, 2013 1:39 AM added example project
    Saturday, December 14, 2013 1:17 AM
  • can you reupload your example?

    thx

    Wednesday, September 07, 2016 12:59 PM