简单暴力,直接上代码
/// <summary> /// 鼠标消息 /// </summary> public struct MouseMSG { public Point p; public IntPtr HWnd; public uint wHitTestCode; public int dwExtraInfo; } /// <summary> /// 键盘消息 /// </summary> public struct KeyBoardMSG { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } public struct KeyValue { public bool IsPressed; public string Key; } //MouseMSG m = (MouseMSG)Marshal.PtrToStructure(lParam, typeof(MouseMSG)); //KeyBoardMSG m = (KeyBoardMSG)Marshal.PtrToStructure(lParam, typeof(KeyBoardMSG)); public class HookHelper { /// <summary> /// 钩子委托 /// </summary> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); /// <summary> /// 安装钩子 /// </summary> /// <param name="idHook">2:线程键盘钩子;13:全局键盘钩子;7:线程鼠标钩子;14:全局鼠标钩子</param> /// <param name="lpfn"></param> /// <param name="hInstance"></param> /// <param name="threadId">如果为0,全局钩子</param> /// <returns></returns> [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); /// <summary> /// 卸载钩子 /// </summary> /// <param name="idHook"></param> /// <returns></returns> [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public 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", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); /// <summary> /// 取得当前线程编号 /// </summary> /// <returns></returns> [DllImport("kernel32.dll")] public static extern int GetCurrentThreadId(); private HookProc keyboardHookProcedure; private int hKeyboardHook = 0; /// <summary> /// 加载钩子 /// </summary> /// <param name="hookProc"></param> public void HookStart(HookProc hookProc) { if (hKeyboardHook == 0) { // 创建HookProc实例 keyboardHookProcedure = new HookProc(hookProc); // 设置线程钩子 //hKeyboardHook = SetWindowsHookEx(2, keyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId()); //设置全局键盘钩子 hKeyboardHook = SetWindowsHookEx(13, keyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0); // 如果设置钩子失败 if (hKeyboardHook == 0) { HookStop(); throw new Exception("SetWindowsHookEx failed."); } } } /// <summary> /// 卸载钩子 /// </summary> public void HookStop() { bool retKeyboard = true; if (hKeyboardHook != 0) { retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; } if (!(retKeyboard && retKeyboard)) throw new Exception("UnhookWindowsHookEx failed."); } /// <summary> /// 获取当前按键值(适用全局钩子) /// </summary> /// <param name="lParam"></param> /// <returns></returns> public KeyValue GetGlobalKeyValue(Int32 wParam, IntPtr lParam) { KeyValue result = new KeyValue(); if (wParam == 0x100) { result.IsPressed = true; } if (wParam == 0x101) { result.IsPressed = false; } KeyBoardMSG m = (KeyBoardMSG)Marshal.PtrToStructure(lParam, typeof(KeyBoardMSG)); int asciiCode = m.vkCode; if (asciiCode >= 0 && asciiCode <= 255) { ASCIIEncoding asciiEncoding = new ASCIIEncoding(); byte[] array = new byte[] { (byte)asciiCode }; result.Key = asciiEncoding.GetString(array); return result; } return result; } }
简单得调用方法
/// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { private HookHelper hookUnit; public MainWindow() { InitializeComponent(); hookUnit = new HookHelper(); hookUnit.HookStart(KeyboardHookProc); } private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { if (nCode >= 0) { textbox1.Text += hookUnit.GetGlobalKeyValue(wParam, lParam); return 1; } return 0; } }
目前存在一个问题,按键无法区分大小写,会持续跟进。