using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; using System.Windows.Interop; namespace WpfHotKey { public class HotKeyHelper { /// <summary> /// 如果函数执行成功,返回值不为0。 /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。.NET方法:Marshal.GetLastWin32Error() /// </summary> /// <param name="hWnd">要定义热键的窗口的句柄</param> /// <param name="id">定义热键ID(不能与其它ID重复) </param> /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param> /// <param name="vk">定义热键的内容,WinForm中可以使用Keys枚举转换, /// WPF中Key枚举是不正确的,应该使用System.Windows.Forms.Keys枚举,或者自定义正确的枚举或int常量</param> /// <returns></returns> [DllImport("user32.dll", SetLastError = true)] static extern bool RegisterHotKey( IntPtr hWnd, int id, KeyModifiers fsModifiers, int vk ); /// <summary> /// 取消注册热键 /// </summary> /// <param name="hWnd">要取消热键的窗口的句柄</param> /// <param name="id">要取消热键的ID</param> /// <returns></returns> [DllImport("user32.dll", SetLastError = true)] static extern bool UnregisterHotKey( IntPtr hWnd, int id ); /// <summary> /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0 /// </summary> /// <param name="lpString"></param> /// <returns></returns> [DllImport("kernel32", SetLastError = true)] static extern short GlobalAddAtom(string lpString); [DllImport("kernel32", SetLastError = true)] static extern short GlobalDeleteAtom(short nAtom); /// <summary> /// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值) /// </summary> [Flags()] public enum KeyModifiers { None = 0, Alt = 1, Ctrl = 2, Shift = 4, WindowsKey = 8 } /// <summary> /// 热键的对应的消息ID /// </summary> public const int WM_HOTKEY = 0x312; static Dictionary<int, Action> keymap = new Dictionary<int, Action>(); //每一个key对于一个处理函数 /// <summary> /// 注册快捷键 /// </summary> /// <param name="window">主体窗体</param> /// <param name="action">回调的方法</param> /// <returns>热键的标识</returns> public static void Regist(Window window, Action action) { HwndSource hWndSource; WindowInteropHelper wih = new WindowInteropHelper(window); hWndSource = HwndSource.FromHwnd(wih.Handle); //添加处理程序 hWndSource.AddHook(MainWindowProc); int KeyCodes = -1; if (!RegisterHotKey(wih.Handle, KeyCodes, HotKeyHelper.KeyModifiers.Ctrl, (int)Keys.S)) { throw new Exception("注册失败"); } else { if (keymap.Where(p => p.Key == KeyCodes).Count() > 0) throw new Exception("注册失败,应为这个组合键已经注册!!"); else { keymap.Add(KeyCodes, action); } } } /// <summary> /// 卸载快捷键 /// </summary> /// <param name="window">主体窗体</param> /// <param name="callBack">注册时回调的方法</param> public static void UnRegist(Window window, Action callBack) { foreach (KeyValuePair<int, Action> var in keymap) { WindowInteropHelper wih = new WindowInteropHelper(window); if (var.Value == callBack) { UnregisterHotKey(wih.Handle, var.Key); keymap.Remove(var.Key); return; } } } private static IntPtr MainWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { case HotKeyHelper.WM_HOTKEY: { int sid = wParam.ToInt32(); if (keymap.Where(p => p.Key == sid).Count() > 0) { keymap.Where(p => p.Key == sid).FirstOrDefault().Value.Invoke(); } handled = true; break; } } return IntPtr.Zero; } } }
时间: 2024-11-06 21:45:38