您的位置:首页 > 编程语言 > C#

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



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: