用途:注册全局组合快捷键和快捷键调用的方法
需要系统钩子,网上有很多方法
下面介绍封装快捷键和注册快捷键方法
/// <summary> 系统快捷键服务 </summary> public class ShortCutHookService { /// <summary> 创建监控引擎 </summary> public void CreateMonitor() { HookKeyboardEngine.KeyUp += HookKeyboardEngine_KeyUp; HookKeyboardEngine.KeyDown += HookKeyboardEngine_KeyDown; _current.Clear(); } /// <summary> 停止殷勤 </summary> public void StopMonitor() { HookKeyboardEngine.KeyUp -= HookKeyboardEngine_KeyUp; HookKeyboardEngine.KeyDown -= HookKeyboardEngine_KeyDown; _current.Clear(); } /// <summary> 按下键 </summary> private void HookKeyboardEngine_KeyDown(object sender, KeyEventArgs e) { KeyEntity k = new KeyEntity(); k.Key = e.KeyCode; k.Time = DateTime.Now; Current.AddDown(k); } /// <summary> 抬起键 </summary> private void HookKeyboardEngine_KeyUp(object sender, KeyEventArgs e) { KeyEntity k = new KeyEntity(); k.Key = e.KeyCode; k.Time = DateTime.Now; Current.RemoveDown(k); Current.Add(k); foreach (var item in _collection) { // Todo :匹配规则触发任务 if (Current.Equals(item.Item1)) { item.Item2.Invoke(); } } } // Todo :匹配规则记录 List<Tuple<ShortCutEntitys, Action>> _collection = new List<Tuple<ShortCutEntitys, Action>>(); ShortCutEntitys _current = new ShortCutEntitys(); /// <summary> 当前按钮记录 </summary> public ShortCutEntitys Current { get => _current; set => _current = value; } /// <summary> 注册执行命令 </summary> public void RegisterCommand(ShortCutEntitys match, Action action) { if (match == null) return; if (_collection.Count == 0) { this.CreateMonitor(); } Tuple<ShortCutEntitys, Action> t = new Tuple<ShortCutEntitys, Action>(match, action); _collection.Add(t); } }
主要用来匹配快捷键,序列化反序列化成文本
/// <summary> 快捷按钮实体 </summary> public class ShortCutEntitys { List<KeyEntity> _keys = new List<KeyEntity>(); /// <summary> 正常按键 </summary> internal List<KeyEntity> Keys { get => _keys; set => _keys = value; } private List<KeyEntity> _downKeys = new List<KeyEntity>(); /// <summary> 按下的按键 </summary> public List<KeyEntity> DownKeys { get { return _downKeys; } set { _downKeys = value; } } /// <summary> 容器的大小 </summary> int capacity = 3; /// <summary> 增加正常按键 </summary> public void Add(KeyEntity key) { Keys.Add(key); if (Keys.Count > 3) { Keys.RemoveAt(0); } } /// <summary> 增加按下的按键 </summary> public void AddDown(KeyEntity key) { if (this.DownKeys.Exists(l => l.Key == key.Key)) return; this.DownKeys.Add(key); } /// <summary> 删除按下的按键 </summary> public void RemoveDown(KeyEntity key) { this.DownKeys.RemoveAll(l => l.Key == key.Key); } /// <summary> 是否包含指定快捷键 </summary> public override bool Equals(object obj) { if (!(obj is ShortCutEntitys)) return false; ShortCutEntitys s = obj as ShortCutEntitys; // Todo :比较按下键 if (this.DownKeys.Count != s.DownKeys.Count) return false; foreach (var item in s.DownKeys) { if (!this.DownKeys.Exists(l => l.Key == item.Key)) return false; } // Todo :非按下键 if (Keys.Count < s.Keys.Count) return false; for (int i = 0; i < s.Keys.Count; i++) { // Todo :比较按键是否一样 if (this.Keys[this.Keys.Count - i - 1].Key != s.Keys[s.Keys.Count - i - 1].Key) { return false; } // Todo :判断时间间隔 if (i == s.Keys.Count - 1) continue; if ((this.Keys[this.Keys.Count - i - 1].Time - this.Keys[this.Keys.Count - i - 2].Time).Seconds > ShortCutConfiger.SplitSecond) { return false; } } return true; } /// <summary> 转换可视化文本 </summary> public override string ToString() { StringBuilder sb = new StringBuilder(); foreach (var item in this._downKeys) { sb.Append(item.Key + ShortCutConfiger.downChar.ToString() + ShortCutConfiger.SptitString.ToString()); } foreach (var item in this.Keys) { sb.Append(item.Key + ShortCutConfiger.SptitString); } return sb.ToString().Trim(ShortCutConfiger.SptitChar); } public void Clear() { this.DownKeys.Clear(); this.Keys.Clear(); } /// <summary> 根据文本生成规则 </summary> public static ShortCutEntitys DeSerilse(string str) { if (string.IsNullOrEmpty(str)) return null; var ss = str.Split(ShortCutConfiger.SptitChar); var ds = ss.ToList().FindAll(l => l.EndsWith(ShortCutConfiger.downChar.ToString())); var ns = ss.Except(ds); ShortCutEntitys s = new ShortCutEntitys(); foreach (var item in ds) { KeyEntity ke = new KeyEntity(); Keys k = (Keys)Enum.Parse(typeof(Keys), item.Trim(ShortCutConfiger.downChar)); ke.Key = k; s.AddDown(ke); } foreach (var item in ns) { KeyEntity ke = new KeyEntity(); Keys k = (Keys)Enum.Parse(typeof(Keys), item.Trim(ShortCutConfiger.downChar)); ke.Key = k; s.Add(ke); } return s; } }
其他配置和实体
/// <summary> 配置信息 </summary> class ShortCutConfiger { /// <summary> 间隔字符 </summary> public const char SptitChar = '+'; /// <summary> 间隔字符串 </summary> public const string SptitString = "+"; /// <summary> 触发范围 </summary> public const double SplitSecond = 0.1; /// <summary> 按下状态 </summary> public const char downChar = '↓'; }
/// <summary> 键盘按键 </summary> public class KeyEntity { private Keys _key; /// <summary> 按下的键 </summary> public Keys Key { get { return _key; } set { _key = value; } } private DateTime _time; /// <summary> 按下的时间 </summary> public DateTime Time { get { return _time; } set { _time = value; } } }
测试代码:
1、按下Shift和D键触发
ShortCutEntitys s= ShortCutEntitys.DeSerilse("LShiftKey↓+D"); Action action2 = () => { s.ToString(); Debug.WriteLine(s.ToString()); }; ShortCutHookService.Instance.RegisterCommand(s, action2);
2、双击D键触发
ShortCutEntitys s = new ShortCutEntitys(); KeyEntity k = new KeyEntity(); k.Key = Keys.D; s.Add(k); KeyEntity c = new KeyEntity(); c.Key = Keys.D; s.Add(c); Action action2 = () => { s.ToString(); Debug.WriteLine(s.ToString()); }; ShortCutHookService.Instance.RegisterCommand(s, action2);
3、按下D键+F键组合
ShortCutEntitys s = new ShortCutEntitys(); KeyEntity k = new KeyEntity(); k.Key = Keys.D; s.AddDown(k); KeyEntity c = new KeyEntity(); c.Key = Keys.F; s.Add(c); Action action2 = () => { s.ToString(); Debug.WriteLine(s.ToString()); }; ShortCutHookService.Instance.RegisterCommand(s, action2);
注:
1、通过此方法可以快速构建快捷键和快捷键对应的方法
2、利用全局钩子构建,可以不用在程序中操作也可以监测
3、按键组合多样