C#接收接盘输入之输入绑定和键盘钩子
项目中遇到用键盘输入来执行流程的需求,然后去搜索,大致搜到下面几种方式:1、事件;2、输入绑定3、键盘钩子
其中事件和输入绑定,只能在窗口激活或控件不失焦的情况才能使用。
键盘钩子属于系统全局的方式,在软件窗口不激活的状态下也能接受指令。
1、事件
//事件很常用,没啥好记的。
2、输入绑定
<Window.InputBindings><KeyBinding Command="{Binding KeyDownCommand}" Gesture="space" />
</Window.InputBindings>
3、键盘钩子
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Input;namespace Keybord
{public class KeyboardHook{public delegate void KeyDownEvent(Key key);public delegate void KeyUpEvent(Key key);/// <summary>/// 键盘钩子句柄/// </summary>private int handleKeyboardHook;private Win32Helper.HookProc keyboardHookDelegate;private KeyDownEvent onKeyDown;private KeyUpEvent onKeyUp;/// <summary>/// 安装键盘钩子/// </summary>public void SetHook(){keyboardHookDelegate = KeyboardHookProc;ProcessModule cModule = Process.GetCurrentProcess().MainModule;if (null == cModule) return;IntPtr moduleHandle = Win32Helper.GetModuleHandle(cModule.ModuleName);handleKeyboardHook = Win32Helper.SetWindowsHookEx(Win32Helper.WH_KEYBOARD_LL, keyboardHookDelegate, moduleHandle, 0);}public void SetOnKeyDownEvent(KeyDownEvent callback){onKeyDown = callback;}public void SetOnKeyUpEvent(KeyUpEvent callback){onKeyUp = callback;}/// <summary>/// 卸载键盘钩子/// </summary>public void UnHook(){bool retKeyboard = true;if (handleKeyboardHook != 0){retKeyboard = Win32Helper.UnhookWindowsHookEx(handleKeyboardHook);handleKeyboardHook = 0;}//如果卸下钩子失败 if (!retKeyboard) throw new Exception("卸下钩子失败!");}/// <summary>/// 获取键盘消息/// </summary>/// <param name="nCode"></param>/// <param name="wParam"></param>/// <param name="lParam"></param>/// <returns></returns>private int KeyboardHookProc(int nCode, int wParam, IntPtr lParam){// 如果该消息被丢弃 nCode<0if (nCode < 0) return Win32Helper.CallNextHookEx(handleKeyboardHook, nCode, wParam, lParam);Win32Helper.KeyboardHookStruct keyboardHookStruct =(Win32Helper.KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Helper.KeyboardHookStruct));Key key = KeyInterop.KeyFromVirtualKey(keyboardHookStruct.vkCode);switch (wParam){case Win32Helper.WM_KEYDOWN:case Win32Helper.WM_SYSKEYDOWN://WM_KEYDOWN和WM_SYSKEYDOWN消息,将会引发OnKeyDownEvent事件// 此处触发键盘按下事件onKeyDown?.Invoke(key);break;case Win32Helper.WM_KEYUP:case Win32Helper.WM_SYSKEYUP://WM_KEYUP和WM_SYSKEYUP消息,将引发OnKeyUpEvent事件// 此处触发键盘抬起事件onKeyUp?.Invoke(key);break;}return Win32Helper.CallNextHookEx(handleKeyboardHook, nCode, wParam, lParam);}}
}
using System;
using System.Runtime.InteropServices;namespace Keybord
{public class Win32Helper{/// <summary>/// 声明回调函数委托/// </summary>/// <param name="nCode"></param>/// <param name="wParam"></param>/// <param name="lParam"></param>/// <returns></returns>public delegate int HookProc(int nCode, int wParam, IntPtr lParam);public const int WM_KEYDOWN = 0x100;public const int WM_KEYUP = 0x101;public const int WM_SYSKEYDOWN = 0x104;public const int WM_SYSKEYUP = 0x105;public const int WH_KEYBOARD_LL = 13;//安装钩子的函数 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);//卸下钩子的函数 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern bool UnhookWindowsHookEx(int idHook);//下一个钩挂的函数 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern IntPtr GetModuleHandle(string lpModuleName);[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]public static extern bool SetForegroundWindow(IntPtr hWnd);[DllImport("winmm.dll", EntryPoint = "mciSendString", CharSet = CharSet.Auto)]public static extern int MciSendString(string lpstrCommand, string lpstrReturnString, int uReturnLength,int hwndCallback);[StructLayout(LayoutKind.Sequential)] //声明键盘钩子的封送结构类型public class KeyboardHookStruct{public int vkCode; //表示一个在1到254间的虚似键盘码 public int scanCode; //表示硬件扫描码 public int flags;public int time;public int dwExtraInfo;}}
}
using System;
using System.Windows;
using System.Windows.Input;
using Keybord;namespace WpfApp1
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{KeyboardHook _keyboardHook;public MainWindow(){InitializeComponent();_keyboardHook = new KeyboardHook();_keyboardHook.SetHook();_keyboardHook.SetOnKeyDownEvent(Win32_Keydown);}protected override void OnClosed(EventArgs eventArgs){_keyboardHook.UnHook();base.OnClosed(eventArgs);}private int i = 0;private void Win32_Keydown(Key key){switch (key){case Key.Escape:{lb.Content = (i++);}break;}}}
}
C#接收接盘输入之输入绑定和键盘钩子相关推荐
- 键盘钩子实现扫码枪输入
钩子 钩子是操作系统消息处理的一种机制.通过钩子,应用程序可以安装一个钩子回调过程让系统调用,从而监视系统中的消息队列.在这些消息到达目标窗口之前对这些消息进行处理. 特点 钩子函数会降低操作系统的性 ...
- 自己写一个键盘钩子程序来监视键盘输入
"钩子是Windows的消息监视点,应用程序可以在这里安装一个监视子程序,这样就可以在系统中的消息流到达目的窗口过程前监控它们" 上面就是WIN32API手册中对钩子的描述.大概就 ...
- ACMNO.22 C语言-公约公倍2 写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果两个整数由键盘输入。 输入 两个数 输出 最大公约数 最小公倍数
题目描述 写两个函数,分别求两个整数的最大公约数和最小公倍数, 用主函数调用这两个函数,并输出结果两个整数由键盘输入. 输入 两个数 输出 最大公约数 最小公倍数 样例输入 6 15 样例输出 3 3 ...
- ACMNO.9求Sn=a+aa+aaa+…+aa…aaa(有n个a)之值,其中a是一个数字。 例如:2+22+222+2222+22222(n=5),n由键盘输入。 输入 n 输出 a=2 时
题目描述 求Sn=a+aa+aaa+-+aa-aaa(有n个a)之值,其中a是一个数字. 例如:2+22+222+2222+22222(n=5),n由键盘输入. 输入 n 输出 a=2 时的Sn 样例 ...
- 重新想象 Windows 8 Store Apps (49) - 输入: 获取输入设备信息, 虚拟键盘, Tab 导航, Pointer, Tap, Drag, Drop...
重新想象 Windows 8 Store Apps (49) - 输入: 获取输入设备信息, 虚拟键盘, Tab 导航, Pointer, Tap, Drag, Drop 原文:重新想象 Window ...
- android自定义金额输入键盘_Android 自定义输入支付密码的软键盘实例代码
Android 自定义输入支付密码的软键盘 有项目需求需要做一个密码锁功能,还有自己的软键盘,类似与支付宝那种,这里是整理的资料,大家可以看下,如有错误,欢迎留言指正 需求:要实现类似支付宝的输入支付 ...
- python怎么输入两行_python交互模式下输入换行/输入多行命令的方法
先给大家介绍下python交互模式下输入换行/输入多行命令的方法 换行方法 \ 如: >>> print 'aaa'; \ ... print 'bbb'; \ ... print ...
- java循环输入直到,使用循环接受其他用户输入,直到用户输入结束输入的值
我是Java的新手 . 我需要一些帮助,使用循环接受其他用户输入,直到用户输入结束输入的值 . 我的问题从语句"System.out.println("你完成了吗?输入大写的Y / ...
- lombok 的bug?lombok 导致 springmvc 使用 @RequestBody注解 接收 json数据 对象参数绑定失败
大家好,我是烤鸭: lombok 导致 springmvc 使用 @RequestBody注解 接收 json数据 对象参数绑定失败. 环境版本: spring 5.x ...
最新文章
- JAVA怎么创建对象组_java – 如何根据特定字段创建一组有序的对象?
- css 背景图怎么设置自动填充满_CSS-布局与定位
- java 检测ip网速_java心跳测网速Demo
- 博士笔记 | 周志华《机器学习》手推笔记第三章-线性模型
- eclipse - 自动换行
- 在按钮上绑定一个图案
- mysql sql 限制条数据类型_数据库的数据类型和约束条件
- oracle 10g在redhat4.6上的安装
- 原生开发跟混合开发两者有什么区别
- 做善良公社项目的经历和感受——善良公社
- 2021年全国计算机能力挑战赛C++决赛,题目分享
- Facebook广告投放策略与优化Facebook广告成效的技巧方式
- java-基于Swing的图形界面设计(上)
- fairyGUI的学习记录2
- 青藏高原对印度意味着什么呢?
- ORA-32017 ORA-16179
- 【更新中】人教版高一数学知识点汇总(必修1)
- PHP 导出excel表格的3种方法
- SpringBoot图文教程9—SpringBoot 导入导出 Excel 「Apache Poi」
- 设计模式(注重理解为什么),