c# 文本框纪录快捷键并处理冲突的系统热键
2016-04-07 18:54
776 查看
/// <summary> /// 取消该事件执行 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txtShortRunagain_KeyPress(object sender, KeyPressEventArgs e) { e.Handled = true; } /// <summary> /// 键盘按键后纪录按键并输出到文本框中 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txtShortRunagain_KeyDown(object sender, KeyEventArgs e) { e.SuppressKeyPress = false; e.Handled = true; MetroFramework.Controls.MetroTextBox txtHotKey = (MetroFramework.Controls.MetroTextBox)sender; txtHotKey.Text = KeyEventArgsToString(e); //MessageBox.Show(txtHotKey.Text); txtHotKey.SelectedStart = txtHotKey.Text.Length; //MessageBox.Show(txtHotKey.Text.Length.ToString()); } /// <summary> /// 按键结束后检测该按键是否正确 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txtShortRunagain_KeyUp(object sender, KeyEventArgs e) { CheckHotkey(sender, e); } /// <summary> /// 将KeyEventArgs实例转换为文本字符串 /// </summary> /// <param name="e"></param> /// <returns></returns> private string KeyEventArgsToString(KeyEventArgs e) { string HotKeyString = ""; if (e.Modifiers != Keys.None) { switch (e.Modifiers) { case Keys.Control: HotKeyString += "Ctrl + "; break; case Keys.Alt: HotKeyString += "Alt + "; break; case Keys.Shift: HotKeyString += "Shift + "; break; case Keys.Control | Keys.Alt: HotKeyString += "Ctrl + Alt + "; break; case Keys.Control | Keys.Shift: HotKeyString += "Ctrl + Shift + "; break; case Keys.Alt | Keys.Shift: HotKeyString += "Alt + Shift + "; break; case Keys.Control | Keys.Alt | Keys.Shift: HotKeyString += "Ctrl + Alt + Shift + "; break; } if (e.KeyCode != Keys.None && e.KeyCode != Keys.ControlKey && e.KeyCode != Keys.Menu && e.KeyCode != Keys.ShiftKey) HotKeyString += KeyCodeToString(e.KeyCode); //System.Console.WriteLine("HotKeyString=" + HotKeyString + "&e.KeyCode=" + e.KeyCode.ToString()); } else { if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back || e.KeyCode == Keys.Tab) HotKeyString = ""; else if (e.KeyCode != Keys.None) HotKeyString = KeyCodeToString(e.KeyCode); } return HotKeyString; } /// <summary> /// 将Keys转换为String类型字符串 /// </summary> /// <param name="KeyCode"></param> /// <returns></returns> private string KeyCodeToString(Keys KeyCode) { if (KeyCode >= Keys.D0 && KeyCode <= Keys.D9) return KeyCode.ToString().Remove(0, 1); else if (KeyCode >= Keys.NumPad0 && KeyCode <= Keys.NumPad9) return KeyCode.ToString().Replace("Pad", ""); else if (KeyCode >= Keys.F1 && KeyCode <= Keys.F12) return KeyCode.ToString(); else if (KeyCode >= Keys.A && KeyCode <= Keys.Z) return KeyCode.ToString(); return ""; } /// <summary> /// 检查是否无实际功能键,是则置无 /// </summary> /// <param name="sender"></param> /// <param name="e">键盘事件实例</param> private void CheckHotkey(object sender, KeyEventArgs e) { MetroFramework.Controls.MetroTextBox txtHotKey = (MetroFramework.Controls.MetroTextBox)sender; if (txtHotKey.Text.EndsWith(" + ")) { txtHotKey.Text = ""; txtHotKey.SelectedStart = txtHotKey.Text.Length; } else { if (string.Compare("", txtHotKey.Text, StringComparison.OrdinalIgnoreCase) == 0) { //判断当前列表中是否存在该键值,如果存在则赋值Null string code = txtHotKey.Tag.ToString(); ShortKey currentKey = currentShortKey[code]; if (currentKey != null) currentShortKey.Remove(currentKey); return; } //处理文本并存储到实体中 ShortKey shortKey = new ShortKey(); string[] textArray = txtHotKey.Text.Trim().ToArray("+"); shortKey.Alt = Array.FindIndex(textArray, p => string.Compare("Alt", p.TrimStart().TrimEnd(), StringComparison.OrdinalIgnoreCase) == 0) >= 0; shortKey.Shift = Array.FindIndex(textArray, p => string.Compare("Shift", p.TrimStart().TrimEnd(), StringComparison.OrdinalIgnoreCase) == 0) >= 0; shortKey.Control = Array.FindIndex(textArray, p => string.Compare("Ctrl", p.TrimStart().TrimEnd(), StringComparison.OrdinalIgnoreCase) == 0) >= 0; shortKey.KeyCode = textArray.Last().ToEnum<Keys>(); if (!currentShortKey.Exists((key) => { if (key == null) return false; if (key.Code == null) return false; //排除掉本身 if (shortKey.Code.Equals(key.Code, StringComparison.OrdinalIgnoreCase)) return false; if (shortKey.Alt == key.Alt && shortKey.Control == key.Control && shortKey.KeyCode == key.KeyCode && shortKey.Shift == key.Shift) return true; return false; })) { errorBox.Visible = false; currentShortKey[txtHotKey.Tag.ToString()] = shortKey; } else { errorBox.Visible = true; errorBox.Text = "已重复设置快捷键"; txtHotKey.Text = ""; currentShortKey.Remove(currentShortKey[txtHotKey.Tag.ToString()]); } } } /// <summary> /// 使用Entert替代Tab执行控件切换 /// </summary> /// <param name="msg"></param> /// <param name="keyData"></param> /// <returns></returns> protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == Keys.Enter && ((!(ActiveControl is MetroFramework.Controls.MetroTextBox) || !((MetroFramework.Controls.MetroTextBox)ActiveControl).AcceptsReturn))) { SendKeys.SendWait("{Tab}"); return true; } return base.ProcessCmdKey(ref msg, keyData); }<pre name="code" class="csharp">/// <summary> /// 加载快捷键 /// </summary> private void initShortKey() { //当前快捷键配置文件 string filepath = System.IO.Path.Combine(UMS.Framework.Basic.PathInfo.ConfigPath, "shortkey.xml"); if (!System.IO.File.Exists(filepath)) return; currentShortKey = UMS.Framework.Basic.XmlUtils.DeserializeFromFile<ShortKeyCollection>(filepath) as ShortKeyCollection; if (currentShortKey == null) return; ShortKey shortKey = null; foreach (Control ctr in this.TabShortKey.Controls) { if (!(ctr is MetroFramework.Controls.MetroTextBox)) continue; if (ctr.Tag == null) continue; shortKey = currentShortKey[ctr.Tag.ToString()]; if (shortKey == null) continue; (ctr as MetroFramework.Controls.MetroTextBox).Text = KeyEventArgsToString(shortKey.KeyEventArgs); (ctr as MetroFramework.Controls.MetroTextBox).SelectedStart = (ctr as MetroFramework.Controls.MetroTextBox).Text.Length; } }
/// <summary> /// 选项卡切换事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void TabOption_SelectedIndexChanged(object sender, EventArgs e) { if (TabOption.SelectedIndex == 0) { this.txtShortRunagain.Focus(); //第一个页面则注册安装钩子 if (keyboardhookHelper == null) keyboardhookHelper = new KeyboardHookHelper(); keyboardhookHelper.InstallHook(OnKeyPress); } else { if (keyboardhookHelper != null) keyboardhookHelper.UninstallHook(); } }
/// <summary> /// 客户端键盘捕捉事件. /// </summary> /// <param name="hookStruct">由Hook程序发送的按键信息</param> /// <param name="handle">是否拦截</param> public void OnKeyPress(KeyboardHookHelper.HookStruct hookStruct, out bool handle) { //预设不拦截任何键 handle = false; Keys key = (Keys)hookStruct.vkCode; //处理键盘按键发送 if (((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt) || ((int)Control.ModifierKeys == (int)Keys.Alt)) { //System.Console.WriteLine("你按下:" + (key == Keys.None ? "" : key.ToString())); if (key != Keys.None) { if (key >= Keys.D0 && key <= Keys.D9) SendKeys.SendWait(key.ToString().ToLower()); else if (key >= Keys.NumPad0 && key <= Keys.NumPad9) SendKeys.SendWait(key.ToString().ToLower()); else if (key >= Keys.F1 && key <= Keys.F12) SendKeys.SendWait(key.ToString().ToLower()); else if (key >= Keys.A && key <= Keys.Z) SendKeys.SendWait(key.ToString().ToLower()); } } }
/// <summary> /// 全局的Hook钩子帮助类 /// </summary> public class KeyboardHookHelper { /// <summary> /// 键盘消息 /// </summary> private const int WH_KEYBOARD_LL = 13; /// <summary> /// 键盘处理事件委托 ,当捕获键盘输入时调用定义该委托的方法. /// </summary> /// <param name="nCode">消息代码</param> /// <param name="wParam">消息代码</param> /// <param name="lParam">当前句柄</param> /// <returns>返回是否执行</returns> private delegate int HookHandle(int nCode, int wParam, IntPtr lParam); /// <summary> /// 客户端键盘处理事件 /// </summary> /// <param name="param">Hook结构</param> /// <param name="handle">返回是否处理</param> public delegate void ProcessKeyHandle(HookStruct param, out bool handle); /// <summary> /// 接收SetWindowsHookEx返回值 /// </summary> private static int _hHookValue = 0; /// <summary> /// 勾子程序处理事件 /// </summary> private HookHandle _KeyBoardHookProcedure; /// <summary> /// Hook结构 /// </summary> [StructLayout(LayoutKind.Sequential)] public class HookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } /// <summary> /// 设置钩子 /// </summary> /// <param name="idHook"></param> /// <param name="lpfn"></param> /// <param name="hInstance"></param> /// <param name="threadId"></param> /// <returns></returns> [DllImport("user32.dll")] private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId); /// <summary> /// 取消钩子 /// </summary> /// <param name="idHook"></param> /// <returns></returns> [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern bool UnhookWindowsHookEx(int idHook); /// <summary> /// 调用下一个钩子 /// </summary> /// <param name="idHook"></param> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> [DllImport("user32.dll")] private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam); /// <summary> /// 获取当前线程ID /// </summary> /// <returns></returns> [DllImport("kernel32.dll")] private static extern int GetCurrentThreadId(); /// <summary> /// Gets the main module for the associated process. /// </summary> /// <param name="name"></param> /// <returns></returns> [DllImport("kernel32.dll")] private static extern IntPtr GetModuleHandle(string name); private IntPtr _hookWindowPtr = IntPtr.Zero; /// <summary> /// 外部调用的键盘处理事件 /// </summary> private static ProcessKeyHandle _clientMethod = null; //构造器 public KeyboardHookHelper() { } /// <summary> /// 安装勾子 /// </summary> /// <param name="hookProcess">外部调用的键盘处理事件</param> public void InstallHook(ProcessKeyHandle clientMethod) { _clientMethod = clientMethod; // 安装键盘钩子 if (_hHookValue == 0) { _KeyBoardHookProcedure = new HookHandle(OnHookProc); _hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName); _hHookValue = SetWindowsHookEx(WH_KEYBOARD_LL, _KeyBoardHookProcedure, _hookWindowPtr, 0); //如果设置钩子失败. if (_hHookValue == 0) UninstallHook(); } } /// <summary> /// 取消钩子事件 /// </summary> public void UninstallHook() { if (_hHookValue != 0) { bool ret = UnhookWindowsHookEx(_hHookValue); if (ret) _hHookValue = 0; } } /// <summary> /// 钩子事件内部调用,调用_clientMethod方法转发到客户端应用。 /// </summary> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> private static int OnHookProc(int nCode, int wParam, IntPtr lParam) { if (nCode >= 0) { //转换结构 HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct)); if (_clientMethod != null) { bool handle = false; //调用客户提供的事件处理程序。 _clientMethod(hookStruct, out handle); //1:表示拦截键盘,return 退出 if (handle) return 1; } } return CallNextHookEx(_hHookValue, nCode, wParam, lParam); } }
相关文章推荐
- C#语言中提供了枚举和整型之间的强制转换功能(SelectItem)
- c#中datagrid控件的基本使用
- C# winfrom 长时间检查不到操作,自动关闭应用程序
- c# 正则表达式如何处理换行符?
- C# 测试代码段性能耗时
- AE+C# 版本更新问题 命名空间“ESRI”中不存在类型或命名空间名称“Arcgis”(是缺少程序集引用吗?)
- C# 反射机制
- 从OC和C#中找乐趣:相同又不同的delegate
- C#中将DataTable转成List
- HP-Socket国产优秀socket通信组件推荐
- C#list泛型的定义,作用,用法
- C# Hadoop
- C#中将数据的格式显示为千分位显示格式
- C# 中资源文件的类型
- C#学习---C#简介
- c# 嵌入的资源
- C#控制台程序中处理2个关闭事件的代码实例
- C#分隔符
- C#未将对象引用设置到对象的事例原因及解决办法
- C#中Thread.Join()的理解