GlobalHotKey.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using System.Windows.Forms;
  5. using System.Windows.Input;
  6. namespace GeekDesk.Util
  7. {
  8. public class GlobalHotKey
  9. {
  10. public enum HotkeyModifiers
  11. {
  12. None = 0,
  13. MOD_ALT = 0x1,
  14. MOD_CONTROL = 0x2,
  15. MOD_SHIFT = 0x4,
  16. MOD_WIN = 0x8
  17. }
  18. private static int currentID;
  19. private static readonly Dictionary<int, InvisibleWindowForMessages> handleTemp = new Dictionary<int, InvisibleWindowForMessages>();
  20. public delegate void HotKeyCallBackHanlder();
  21. /// <summary>
  22. /// Registers a global hotkey
  23. /// </summary>
  24. /// <param name="aKeyGestureString">e.g. Alt + Shift + Control + Win + S</param>
  25. /// <param name="callback">Action to be called when hotkey is pressed</param>
  26. /// <returns>true, if registration succeeded, otherwise false</returns>
  27. public static int RegisterHotKey(string aKeyGestureString, HotKeyCallBackHanlder callback)
  28. {
  29. var c = new KeyGestureConverter();
  30. KeyGesture aKeyGesture = (KeyGesture)c.ConvertFrom(aKeyGestureString);
  31. return RegisterHotKey((HotkeyModifiers)aKeyGesture.Modifiers, aKeyGesture.Key, callback);
  32. }
  33. public static int RegisterHotKey(HotkeyModifiers aModifier, Key key, HotKeyCallBackHanlder callback)
  34. {
  35. InvisibleWindowForMessages window = new InvisibleWindowForMessages(callback);
  36. currentID += 1;
  37. if (!RegisterHotKey(window.Handle, currentID, aModifier, (uint)KeyInterop.VirtualKeyFromKey(key)))
  38. {
  39. window.Dispose();
  40. throw new Exception("RegisterHotKey Failed");
  41. }
  42. handleTemp.Add(currentID, window);
  43. return currentID;
  44. }
  45. public static void Dispose(int id)
  46. {
  47. try
  48. {
  49. UnregisterHotKey(handleTemp[id].Handle, id);
  50. GlobalHotKey.handleTemp[id].Dispose();
  51. GlobalHotKey.handleTemp.Remove(id);
  52. }
  53. catch
  54. {
  55. //nothing
  56. }
  57. }
  58. // Registers a hot key with Windows.
  59. [DllImport("user32.dll")]
  60. private static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyModifiers fsModifiers, uint vk);
  61. // Unregisters the hot key with Windows.
  62. [DllImport("user32.dll")]
  63. private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
  64. private class InvisibleWindowForMessages : NativeWindow, IDisposable
  65. {
  66. public event HotKeyCallBackHanlder callback;
  67. public InvisibleWindowForMessages(HotKeyCallBackHanlder callback)
  68. {
  69. CreateHandle(new CreateParams());
  70. this.callback += callback;
  71. }
  72. private static readonly int WM_HOTKEY = 0x0312;
  73. protected override void WndProc(ref Message m)
  74. {
  75. base.WndProc(ref m);
  76. if (m.Msg == WM_HOTKEY)
  77. {
  78. callback();
  79. }
  80. }
  81. public void Dispose()
  82. {
  83. this.DestroyHandle();
  84. }
  85. }
  86. }
  87. }