本例支持单键和组合键,不过注册的是操作系统的全局快捷键,这点需要注意,在代码中要做屏蔽处理
先建一个快捷键的工具类
public class HotKey { //定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值) [Flags] public enum KeyModifiers { None = 0,Alt = 1,Ctrl = 2,Shift = 4,WindowsKey = 8 } //如果函数执行成功,返回值不为0。 //如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。 [DllImport("user32.dll",SetLastError = true)] public static extern bool RegisterHotKey( IntPtr hWnd,//要定义热键的窗口的句柄 int id,//定义热键ID(不能与其它ID重复) KeyModifiers fsModifiers,//标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效 Keys vk //定义热键的内容 ); [DllImport("user32.dll",SetLastError = true)] public static extern bool UnregisterHotKey( IntPtr hWnd,//要取消热键的窗口的句柄 int id //要取消热键的ID ); }快捷键配置类似下面这样
<HotKey Keys =" Ctrl+D1" Code ="100"> <CallMethod Name ="GisSelect" /> </HotKey> <HotKey Keys ="F2" Code ="101"> <CallMethod Name ="GisZoomIn" /> </HotKey> <HotKey Keys ="F3" Code ="102"> <CallMethod Name ="GisZoomOut" /> </HotKey> <HotKey Keys ="Ctrl + D0" Code ="103"> <CallMethod Name ="GisReset" /> </HotKey>CallMethod为反射调用的方法
var hotKeys = ToolStripConfig.FindHotKeys(compositeView.SmartPartsName,compositeView.SmartParts[0].ToString()); if (hotKeys != null) { var keyModifiersFields = typeof(HotKey.KeyModifiers).GetFields(BindingFlags.Static | BindingFlags.Public); var keys = typeof(Keys).GetFields(BindingFlags.Static | BindingFlags.Public); foreach (XElement hotKey in hotKeys) { var keyNameList = new List<string>(); hotKey.Attribute("Keys").Value.Split('+').ToList().ForEach(item => keyNameList.Add(item.Trim())); //处理KeyModifiers var keyModifiersFieldsValueList = (from fi in keyModifiersFields where keyNameList.Contains(fi.Name) select (HotKey.KeyModifiers)fi.GetValue(null)).ToList(); //处理Keys var keysValueList = (from fi in keys where keyNameList.Contains(fi.Name) select (Keys)fi.GetValue(null)).ToList(); //组合键 if (keyNameList.Count > 1) { //注册快捷键 if (keyModifiersFieldsValueList.Count > 1) HotKey.RegisterHotKey(Handle,int.Parse(hotKey.Attribute("Code").Value),keyModifiersFieldsValueList[0] | keyModifiersFieldsValueList[1],keysValueList[0]); else HotKey.RegisterHotKey(Handle,keyModifiersFieldsValueList[0],keysValueList[0]); } //单键 else { //注册快捷键 HotKey.RegisterHotKey(Handle,keysValueList[0]); } } }
接着在窗体代码中对windows消息进行拦截,对键盘按键进行捕捉,读取配置文件,反射执行对应的配置方法
protected override void WndProc(ref Message m) { var compositeView = _presenter.WorkItem.RootWorkItem.Workspaces[XSWorkSpaceConst.CONTENTWORKSPACE].ActiveSmartPart as CompSmartPartZoneView; if (compositeView != null && compositeView.SmartParts.Count > 0 && Equals(compositeView.SmartParts[0] as XSView)) { //只有当前窗口是系统窗口,快捷键才响应 var findWindow = Control.FromHandle(GetForegroundWindow()); if (findWindow != null && findWindow.GetType().Name == "XSShellMainForm") { //快捷键响应,反射调用配置的方法 var hotKeys = ToolStripConfig.FindHotKeys(compositeView.SmartPartsName,compositeView.SmartParts[0].ToString()); if (hotKeys != null) { foreach (XElement hotKey in hotKeys) { if (m.WParam.ToInt32() == int.Parse(hotKey.Attribute("Code").Value)) { Type t = compositeView.SmartParts[0].GetType(); RunSmartConfig.CallMethods(compositeView.SmartParts[0],t,hotKey.Elements("CallMethod")); } } } } } base.WndProc(ref m); }
以上的 XSShellMainForm为当前主窗体的Type类型名称
最后在关闭窗体的时候,还要注销这个快捷键,这个过程同样要读取XML
var hotKeys = ToolStripConfig.FindHotKeys(compositeView.SmartPartsName,compositeView.SmartParts[0].ToString()); if (hotKeys != null) { foreach (XElement hotKey in hotKeys) { HotKey.UnregisterHotKey(Handle,int.Parse(hotKey.Attribute("Code").Value)); } }