Winform程序全局热键
Winform程序全局热键一般采用的是,调用windows api的形式,主要是通过下面的四个函数
/// <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)] public static extern bool RegisterHotKey( IntPtr hWnd, UInt32 id, UInt32 fsModifiers, UInt32 vk );
/// <summary> /// 取消注册热键 /// </summary> /// <param name="hWnd">要取消热键的窗口的句柄</param> /// <param name="id">要取消热键的ID</param> /// <returns></returns> [DllImport("user32.dll", SetLastError = true)] public static extern bool UnregisterHotKey( IntPtr hWnd, UInt32 id );
/// <summary> /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0 /// </summary> /// <param name="lpString"></param> /// <returns></returns> [DllImport("kernel32", SetLastError = true)] public static extern UInt32 GlobalAddAtom(string lpString);
/// <summary> /// 从全局原子表删除指定一个字符串,并返回这个字符串的唯一标识符,失败返回0 /// </summary> /// <param name="nAtom"></param> /// <returns></returns> [DllImport("kernel32", SetLastError = true)] public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom);
还有一个辅助类,标志用户是否注册了含有win ctrl shift等特殊键的快捷方式
/// <summary> /// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值) /// </summary> public enum KeyFlags { MOD_NONE = 0x0, MOD_ALT = 0x1, MOD_CONTROL = 0x2, MOD_SHIFT = 0x4, MOD_WIN = 0x8 }
贴上全部代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Collections; namespace luolunz { public delegate void HotkeyEventHandler(int hotKeyID); public class HotkeyHelper : IMessageFilter { public event HotkeyEventHandler OnHotkey; public enum KeyFlags { MOD_NONE=0x0, MOD_ALT = 0x1, MOD_CONTROL = 0x2, MOD_SHIFT = 0x4, MOD_WIN = 0x8 } class NativeMethods { private NativeMethods() { } #region WIN32 API /// <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)] public static extern bool RegisterHotKey( IntPtr hWnd, UInt32 id, UInt32 fsModifiers, UInt32 vk ); /// <summary> /// 取消注册热键 /// </summary> /// <param name="hWnd">要取消热键的窗口的句柄</param> /// <param name="id">要取消热键的ID</param> /// <returns></returns> [DllImport("user32.dll", SetLastError = true)] public static extern bool UnregisterHotKey( IntPtr hWnd, UInt32 id ); /// <summary> /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0 /// </summary> /// <param name="lpString"></param> /// <returns></returns> [DllImport("kernel32", SetLastError = true)] public static extern UInt32 GlobalAddAtom(string lpString); /// <summary> /// 从全局原子表删除指定一个字符串,并返回这个字符串的唯一标识符,失败返回0 /// </summary> /// <param name="nAtom"></param> /// <returns></returns> [DllImport("kernel32", SetLastError = true)] public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom); /// <summary> /// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值) /// </summary> public enum KeyFlags { MOD_NONE = 0x0, MOD_ALT = 0x1, MOD_CONTROL = 0x2, MOD_SHIFT = 0x4, MOD_WIN = 0x8 } #endregion } Hashtable keyIDs = new Hashtable(); IntPtr hWnd; public HotkeyHelper(IntPtr hWnd) { this.hWnd = hWnd; Application.AddMessageFilter(this); } public UInt32RegisterHotkey(Keys Key, KeyFlags keyflags) { UInt32 hotkeyid = NativeMethods.GlobalAddAtom(System.Guid.NewGuid().ToString()); NativeMethods.RegisterHotKey((IntPtr)hWnd, hotkeyid, (UInt32)keyflags, (UInt32)Key); keyIDs.Add(hotkeyid, hotkeyid); return (UInt32)hotkeyid; } public void UnregisterHotkeys() { Application.RemoveMessageFilter(this); foreach (UInt32 key in keyIDs.Values) { NativeMethods.UnregisterHotKey(hWnd, key); NativeMethods.GlobalDeleteAtom(key); } } public bool PreFilterMessage(ref Message m) { if (m.Msg == 0x312) { if (OnHotkey != null) { foreach (UInt32 key in keyIDs.Values) { if ((UInt32)m.WParam == key) { OnHotkey((int)m.WParam); return true; } } } } return false; } } }
使用方式:
HotkeyHelper HotkeyHelper { set; get; } UInt32 CONTROR_F; UInt32 CONTROR_G; UInt32 F10; HotkeyHelper = new HotkeyHelper(this.Handle); CONTROR_F = HotkeyHelper.RegisterHotkey(Keys.F, HotkeyHelper.KeyFlags.MOD_CONTROL | HotkeyHelper.KeyFlags.MOD_SHIFT); CONTROR_G = HotkeyHelper.RegisterHotkey(Keys.G, HotkeyHelper.KeyFlags.MOD_CONTROL); F10 = HotkeyHelper.RegisterHotkey(Keys.F10, 0); HotkeyHelper.OnHotkey += new HotkeyEventHandler(OnHotkey); private void OnHotkey(int hotkeyID) { if (hotkeyID == CONTROR_F) { //do something MessageBox.Show("CONTROR_SHIT_F"); } else if (hotkeyID == F10) { //do something else MessageBox.Show("F10"); } }
局部热键(键盘快捷键的捕获)
/// <summary> /// 用户键盘快捷键获取与处理 /// </summary> /// <param name="msg"></param> /// <param name="keyData"></param> /// <returns></returns> protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { KeyEventArgs e = new KeyEventArgs(keyData); if (keyData == (Keys.Alt | Keys.P)) { //do something
} if (keyData == (Keys.Alt | Keys.C)) { //do something
} if (keyData == (Keys.Alt | Keys.A)) { //do something
} if (keyData == (Keys.Alt | Keys.Z)) { //do something
} if (keyData == (Keys.F1)) { //do something
} if (keyData == (Keys.F3)) { //do something
} return true; }