c# 文本框纪录快捷键并处理冲突的系统热键

 /// <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);
        }
    }



 

猜你喜欢

转载自blog.csdn.net/fuweiping/article/details/51088386