Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I register a global hot key to say CTRL+SHIFT+(LETTER) using WPF and .NET 3.5?

I'm building an application in C# using WPF. How can I bind to some keys?

Also, how can I bind to the Windows key?

like image 876
w-ll Avatar asked Sep 08 '08 00:09

w-ll


1 Answers

This is a full working solution, hope it helps...

Usage:

_hotKey = new HotKey(Key.F9, KeyModifier.Shift | KeyModifier.Win, OnHotKeyHandler); 

...

private void OnHotKeyHandler(HotKey hotKey) {     SystemHelper.SetScreenSaverRunning(); } 

Class:

using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net.Mime; using System.Runtime.InteropServices; using System.Text; using System.Windows; using System.Windows.Input; using System.Windows.Interop;  namespace UnManaged {     public class HotKey : IDisposable     {         private static Dictionary<int, HotKey> _dictHotKeyToCalBackProc;          [DllImport("user32.dll")]         private static extern bool RegisterHotKey(IntPtr hWnd, int id, UInt32 fsModifiers, UInt32 vlc);          [DllImport("user32.dll")]         private static extern bool UnregisterHotKey(IntPtr hWnd, int id);          public const int WmHotKey = 0x0312;          private bool _disposed = false;          public Key Key { get; private set; }         public KeyModifier KeyModifiers { get; private set; }         public Action<HotKey> Action { get; private set; }         public int Id { get; set; }          // ******************************************************************         public HotKey(Key k, KeyModifier keyModifiers, Action<HotKey> action, bool register = true)         {             Key = k;             KeyModifiers = keyModifiers;             Action = action;             if (register)             {                 Register();             }         }          // ******************************************************************         public bool Register()         {             int virtualKeyCode = KeyInterop.VirtualKeyFromKey(Key);             Id = virtualKeyCode + ((int)KeyModifiers * 0x10000);             bool result = RegisterHotKey(IntPtr.Zero, Id, (UInt32)KeyModifiers, (UInt32)virtualKeyCode);              if (_dictHotKeyToCalBackProc == null)             {                 _dictHotKeyToCalBackProc = new Dictionary<int, HotKey>();                 ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ComponentDispatcherThreadFilterMessage);             }              _dictHotKeyToCalBackProc.Add(Id, this);              Debug.Print(result.ToString() + ", " + Id + ", " + virtualKeyCode);             return result;         }          // ******************************************************************         public void Unregister()         {             HotKey hotKey;             if (_dictHotKeyToCalBackProc.TryGetValue(Id, out hotKey))             {                 UnregisterHotKey(IntPtr.Zero, Id);             }         }          // ******************************************************************         private static void ComponentDispatcherThreadFilterMessage(ref MSG msg, ref bool handled)         {             if (!handled)             {                 if (msg.message == WmHotKey)                 {                     HotKey hotKey;                      if (_dictHotKeyToCalBackProc.TryGetValue((int)msg.wParam, out hotKey))                     {                         if (hotKey.Action != null)                         {                             hotKey.Action.Invoke(hotKey);                         }                         handled = true;                     }                 }             }         }          // ******************************************************************         // Implement IDisposable.         // Do not make this method virtual.         // A derived class should not be able to override this method.         public void Dispose()         {             Dispose(true);             // This object will be cleaned up by the Dispose method.             // Therefore, you should call GC.SupressFinalize to             // take this object off the finalization queue             // and prevent finalization code for this object             // from executing a second time.             GC.SuppressFinalize(this);         }          // ******************************************************************         // Dispose(bool disposing) executes in two distinct scenarios.         // If disposing equals true, the method has been called directly         // or indirectly by a user's code. Managed and unmanaged resources         // can be _disposed.         // If disposing equals false, the method has been called by the         // runtime from inside the finalizer and you should not reference         // other objects. Only unmanaged resources can be _disposed.         protected virtual void Dispose(bool disposing)         {             // Check to see if Dispose has already been called.             if (!this._disposed)             {                 // If disposing equals true, dispose all managed                 // and unmanaged resources.                 if (disposing)                 {                     // Dispose managed resources.                     Unregister();                 }                  // Note disposing has been done.                 _disposed = true;             }         }     }      // ******************************************************************     [Flags]     public enum KeyModifier     {         None = 0x0000,         Alt = 0x0001,         Ctrl = 0x0002,         NoRepeat = 0x4000,         Shift = 0x0004,         Win = 0x0008     }      // ****************************************************************** } 
like image 157
Eric Ouellet Avatar answered Sep 29 '22 06:09

Eric Ouellet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!