更优雅的实现注册热键

This commit is contained in:
liufei
2021-08-20 15:43:02 +08:00
parent 6ecb55061f
commit 8d44429bda

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using System.Windows.Forms;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop; using System.Windows.Interop;
@@ -18,9 +19,7 @@ namespace GeekDesk.Util
} }
private static int currentID; private static int currentID;
const int WM_HOTKEY = 0x312; private static readonly Dictionary<int, InvisibleWindowForMessages> handleTemp = new Dictionary<int, InvisibleWindowForMessages>();
private static Dictionary<int, Window> handleTemp = new Dictionary<int, Window>();
public static Dictionary<int, HotKeyCallBackHanlder> callbackTemp = new Dictionary<int, HotKeyCallBackHanlder>();
public delegate void HotKeyCallBackHanlder(); public delegate void HotKeyCallBackHanlder();
/// <summary> /// <summary>
@@ -38,50 +37,22 @@ namespace GeekDesk.Util
public static int RegisterHotKey(HotkeyModifiers aModifier, Key key, HotKeyCallBackHanlder callback) public static int RegisterHotKey(HotkeyModifiers aModifier, Key key, HotKeyCallBackHanlder callback)
{ {
Window window = new Window InvisibleWindowForMessages window = new InvisibleWindowForMessages(callback);
{
WindowStyle = WindowStyle.None,
Height = 0,
Width = 0,
Visibility = Visibility.Collapsed,
ShowInTaskbar = false
};
window.Show();
IntPtr handle = new WindowInteropHelper(window).Handle;
HwndSource hs = HwndSource.FromHwnd(handle);
hs.AddHook(WndProc);
currentID += 1; currentID += 1;
if (!RegisterHotKey(handle, currentID, aModifier, (uint)KeyInterop.VirtualKeyFromKey(key))) if (!RegisterHotKey(window.Handle, currentID, aModifier, (uint)KeyInterop.VirtualKeyFromKey(key)))
{ {
window.Close(); window.Dispose();
throw new Exception("RegisterHotKey Failed"); throw new Exception("RegisterHotKey Failed");
} }
handleTemp.Add(currentID, window); handleTemp.Add(currentID, window);
callbackTemp.Add(currentID, callback);
return currentID; return currentID;
} }
/// <summary>
/// 快捷键消息处理
/// </summary>
static IntPtr WndProc(IntPtr windowHandle, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_HOTKEY)
{
int id = wParam.ToInt32();
if (callbackTemp.TryGetValue(id, out var callback))
{
callback();
}
}
return IntPtr.Zero;
}
public static void Dispose(int id) public static void Dispose(int id)
{ {
bool test = UnregisterHotKey(new WindowInteropHelper(handleTemp[id]).Handle, id); bool test = UnregisterHotKey(handleTemp[id].Handle, id);
GlobalHotKey.handleTemp[id].Close(); GlobalHotKey.handleTemp[id].Dispose();
GlobalHotKey.handleTemp.Remove(id); GlobalHotKey.handleTemp.Remove(id);
GlobalHotKey.callbackTemp.Remove(id);
Console.WriteLine(test); Console.WriteLine(test);
} }
@@ -91,5 +62,31 @@ namespace GeekDesk.Util
// Unregisters the hot key with Windows. // Unregisters the hot key with Windows.
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id); private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private class InvisibleWindowForMessages : NativeWindow, IDisposable
{
public event HotKeyCallBackHanlder callback;
public InvisibleWindowForMessages(HotKeyCallBackHanlder callback)
{
CreateHandle(new CreateParams());
this.callback += callback;
}
private static readonly int WM_HOTKEY = 0x0312;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_HOTKEY)
{
callback();
}
}
public void Dispose()
{
this.DestroyHandle();
}
}
}
} }
}