C#打造机械耳感键盘(全局监听键盘并设置音效)
2020-07-14 06:11
645 查看
很多小盆友表示买不起机械键盘,甚至买不起机械手感键盘,一直在用笔记本自带的键盘。那么如何改造成机械键盘?废话不多说,上代码。
1.首先写一个全局监听键盘的类,主要是利用勾子实现。
using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace KeyboardMusic { class KeyBoardHook { //需要绑定的事件 public event KeyEventHandler KeyUpEvent; public event KeyEventHandler KeyDownEvent; public event KeyPressEventHandler KeyPressEvent; public delegate int HookProc(int nCode, int wParam, IntPtr lParam); static int hKeyboardHook = 0; //声明键盘钩子处理的初始值 public const int WH_KEYBOARD_LL = 13;//全局键盘监听鼠标消息为13 HookProc KeyboardHookProcedure; [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } //安装钩子 [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, Int32 wParam, IntPtr lParam); // 取得当前线程编号 [DllImport("kernel32.dll")] static extern int GetCurrentThreadId(); //防止钩子失效 [DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string name); public void Start() { // 安装键盘钩子 if (hKeyboardHook == 0) { KeyboardHookProcedure = new HookProc(KeyboardHookProc); hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0); if (hKeyboardHook == 0) { Stop(); throw new Exception("安装失败"); } } } public void Stop() { bool retKeyboard = true; if (hKeyboardHook != 0) { retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; } if (!(retKeyboard)) throw new Exception("卸载钩子失败!"); } //ToAscii职能的转换指定的虚拟键码和键盘状态的相应字符或字符 [DllImport("user32")] public static extern int ToAscii(int uVirtKey, //[in] 指定虚拟关键代码进行翻译。 int uScanCode, // [in] 指定的硬件扫描码的关键须翻译成英文。高阶位的这个值设定的关键,如果是(不压) byte[] lpbKeyState, // [in] 指针,以256字节数组,包含当前键盘的状态。每个元素(字节)的数组包含状态的一个关键。如果高阶位的字节是一套,关键是下跌(按下)。在低比特,如果设置表明,关键是对切换。在此功能,只有肘位的CAPS LOCK键是相关的。在切换状态的NUM个锁和滚动锁定键被忽略。 byte[] lpwTransKey, // [out] 指针的缓冲区收到翻译字符或字符。 int fuState); // [in] Specifies whether a menu is active. This parameter must be 1 if a menu is active, or 0 otherwise. //获取按键的状态 [DllImport("user32")] public static extern int GetKeyboardState(byte[] pbKeyState); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern short GetKeyState(int vKey); private const int WM_KEYDOWN = 0x100;//KEYDOWN private const int WM_KEYUP = 0x101;//KEYUP private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN private const int WM_SYSKEYUP = 0x105;//SYSKEYUP private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { // 侦听键盘事件 if ((nCode >= 0) && (KeyDownEvent != null || KeyUpEvent != null || KeyPressEvent != null)) { KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); // 键盘按下 if (KeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) { Keys keyData = (Keys)MyKeyboardHookStruct.vkCode; KeyEventArgs e = new KeyEventArgs(keyData); KeyDownEvent(this, e); } //键盘按着 if (KeyPressEvent != null && wParam == WM_KEYDOWN) { byte[] keyState = new byte[256]; GetKeyboardState(keyState); byte[] inBuffer = new byte[2]; if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1) { KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]); KeyPressEvent(this, e); } } // 键盘抬起 if (KeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)) { Keys keyData = (Keys)MyKeyboardHookStruct.vkCode; KeyEventArgs e = new KeyEventArgs(keyData); KeyUpEvent(this, e); } } return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } ~KeyBoardHook() { Stop(); } } }
2.在form_load事件中调用这个类安装钩子,并且注册事件
KeyBoardHook k_hook = new KeyBoardHook(); k_hook.KeyDownEvent += new KeyEventHandler(hook_KeyDown);//钩住键按下 k_hook.KeyUpEvent += new KeyEventHandler(hook_KeyUp);//钩住键按下 k_hook.Start();//安装键盘钩子
3.自己想办法搞一个机械键盘的音效去,注意必须是两个wav文件,一个是按下,一个是抬起
private void hook_KeyDown(object sender, KeyEventArgs e) { //单独键盘按键 //string keyCode = e.KeyCode.ToString(); string m = Application.StartupPath.Replace(@"\", @"/") + @"/wav/mechanicalKeyboard_down.wav"; using (System.Media.SoundPlayer sndPlayer = new System.Media.SoundPlayer(m)) { sndPlayer.Play(); } } private void hook_KeyUp(object sender, KeyEventArgs e) { string m = Application.StartupPath.Replace(@"\", @"/") + @"/wav/mechanicalKeyboard_up.wav"; using (System.Media.SoundPlayer sndPlayer = new System.Media.SoundPlayer(m)) { sndPlayer.Play(); } }
4.这样就可以实现机械耳感键盘啦,如果你有兴趣,可以通过e.KeyCode获取你按下的具体数值按键,进而设置不同的音效,本人就搞了一个,他会说出你按下的键,像极了计算器,非常沙雕。。。
如果喜欢就点个赞哇!!!
相关文章推荐
- C#全局键盘监听(Hook)的使用(转载)
- C#全局键盘监听
- C#全局键盘监听(Hook)的使用
- C# 计算器 如果设置键盘输入的监听事件
- 【转】【C#】全局键盘监听
- c# WinForm 全局键盘事件怎么监听
- C#全局键盘监听(Hook)
- c# WinForm 全局键盘事件怎么监听
- C#全局键盘监听(Hook)的使用
- C# 非阻塞监听键盘输入
- java全局鼠标键盘监听
- c# 全局钩子之键盘 (实例)
- input设置键盘监听事件
- 监听全局键盘的弹出与隐藏状态
- 全局钩子监听键盘鼠标事件
- Flex 自动获取焦点 监听全局键盘事件
- C#全局键盘钩子
- 如何在C#中使用全局鼠标、键盘Hook
- C#监测全局键盘与鼠标事件
- C# 捕获键盘按键的消息,设置…