在C#中一般不能用SetWindowHookEx监视全局键盘与鼠标事件,微软给出的解释是托管程序不能与非托管共享链接库交互,在网上找了老半天才发现了这个解决方案,拿出来与大家分享一下,希望可以节约对这方面又需求和希望学习的朋友们的时间. WH_KEYBOARD_LL和WH_MOUSE_LL是个例外,可以做到对全局鼠标与键盘事件监控.具体示例代码如下: using System; using System.Runtime.InteropServices; using System.Reflection; using System.Threading; using System.Windows.Forms; using System.ComponentModel; namespace ScreenCapyure2 { public class UserActivityHook { #region Windows structure definitions [StructLayout(LayoutKind.Sequential)] private class POINT { public int x; public int y; } [StructLayout(LayoutKind.Sequential)] private class MouseHookStruct { public POINT pt; public int hwnd; public int wHitTestCode; public int dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] private class MouseLLHookStruct { public POINT pt; public int mouseData; public int flags; public int time; public int dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] private class KeyboardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } #endregion #region Windows function imports [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] private static extern int SetWindowsHookEx( int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] private static extern int UnhookWindowsHookEx(int idHook); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern int CallNextHookEx( int idHook, int nCode, int wParam, IntPtr lParam); private delegate int HookProc(int nCode, int wParam, IntPtr lParam); [DllImport("user32")] private static extern int ToAscii( int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState); [DllImport("user32")] private static extern int GetKeyboardState(byte[] pbKeyState); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern short GetKeyState(int vKey); #endregion #region Windows constants private const int WH_MOUSE_LL = 14; private const int WH_KEYBOARD_LL = 13; private const int WH_MOUSE = 7; private const int WH_KEYBOARD = 2; private const int WM_MOUSEMOVE = 0x200; private const int WM_LBUTTONDOWN = 0x201; private const int WM_RBUTTONDOWN = 0x204; private const int WM_MBUTTONDOWN = 0x207; private const int WM_LBUTTONUP = 0x202; private const int WM_RBUTTONUP = 0x205; private const int WM_MBUTTONUP = 0x208; private const int WM_LBUTTONDBLCLK = 0x203; private const int WM_RBUTTONDBLCLK = 0x206; private const int WM_MBUTTONDBLCLK = 0x209; private const int WM_MOUSEWHEEL = 0x020A; private const int WM_KEYDOWN = 0x100; private const int WM_KEYUP = 0x101; private const int WM_SYSKEYDOWN = 0x104; private const int WM_SYSKEYUP = 0x105; private const byte VK_SHIFT = 0x10; private const byte VK_CAPITAL = 0x14; private const byte VK_NUMLOCK = 0x90; #endregion public UserActivityHook() { Start(); } public UserActivityHook(bool InstallMouseHook, bool InstallKeyboardHook) { Start(InstallMouseHook, InstallKeyboardHook); } ~UserActivityHook() { Stop(true, true, false); } public event MouseEventHandler OnMouseActivity; public event KeyEventHandler KeyDown; public event KeyPressEventHandler KeyPress; public event KeyEventHandler KeyUp; private int hMouseHook = 0; private int hKeyboardHook = 0; private static HookProc MouseHookProcedure; private static HookProc KeyboardHookProcedure; public void Start() { this.Start(true, true); } public void Start(bool InstallMouseHook, bool InstallKeyboardHook) { if (hMouseHook == 0 && InstallMouseHook) { MouseHookProcedure = new HookProc(MouseHookProc); hMouseHook = SetWindowsHookEx( WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE( Assembly.GetExecutingAssembly().GetModules()[0]), 0); if (hMouseHook == 0) { int errorCode = Marshal.GetLastWin32Error(); Stop(true, false, false); throw new Win32Exception(errorCode); } } if (hKeyboardHook == 0 && InstallKeyboardHook) { KeyboardHookProcedure = new HookProc(KeyboardHookProc); hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE( Assembly.GetExecutingAssembly().GetModules()[0]), 0); if (hKeyboardHook == 0) { int errorCode = Marshal.GetLastWin32Error(); Stop(false, true, false); throw new Win32Exception(errorCode); } } } public void Stop() { this.Stop(true, true, true); } public void Stop(bool UninstallMouseHook, bool UninstallKeyboardHook, bool ThrowExceptions) { if (hMouseHook != 0 && UninstallMouseHook) { int retMouse = UnhookWindowsHookEx(hMouseHook); hMouseHook = 0; if (retMouse == 0 && ThrowExceptions) { int errorCode = Marshal.GetLastWin32Error(); throw new Win32Exception(errorCode); } } if (hKeyboardHook != 0 && UninstallKeyboardHook) { int retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; if (retKeyboard == 0 && ThrowExceptions) { int errorCode = Marshal.GetLastWin32Error(); throw new Win32Exception(errorCode); } } } private int MouseHookProc(int nCode, int wParam, IntPtr lParam) { if ((nCode >= 0) && (OnMouseActivity != null)) { MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct)); MouseButtons button = MouseButtons.None; short mouseDelta = 0; switch (wParam) { case WM_LBUTTONDOWN: button = MouseButtons.Left; break; case WM_LBUTTONUP: button = MouseButtons.Right; break; case WM_MOUSEWHEEL: mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff); break; } int clickCount = 0; if (button != MouseButtons.None) if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = 2; else clickCount = 1; MouseEventArgs e = new MouseEventArgs( button, clickCount, mouseHookStruct.pt.x, mouseHookStruct.pt.y, mouseDelta); OnMouseActivity(this, e); } return CallNextHookEx(hMouseHook, nCode, wParam, lParam); } private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { bool handled = false; if ((nCode >= 0) && (KeyDown != null || KeyUp != null || KeyPress != null)) { KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); if (KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) { Keys keyData = (Keys)MyKeyboardHookStruct.vkCode; KeyEventArgs e = new KeyEventArgs(keyData); KeyDown(this, e); handled = handled || e.Handled; } if (KeyPress != null && wParam == WM_KEYDOWN) { bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true : false); bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false); byte[] keyState = new byte[256]; GetKeyboardState(keyState); byte[] inBuffer = new byte[2]; if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1) { char key = (char)inBuffer[0]; if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.ToUpper(key); KeyPressEventArgs e = new KeyPressEventArgs(key); KeyPress(this, e); handled = handled || e.Handled; } } if (KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)) { Keys keyData = (Keys)MyKeyboardHookStruct.vkCode; KeyEventArgs e = new KeyEventArgs(keyData); KeyUp(this, e); handled = handled || e.Handled; } } if (handled) return 1; else return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } } } 以下为在窗体中监视事件 UserActivityHook choosesc; choosesc = new UserActivityHook(); choosesc.OnMouseActivity += new MouseEventHandler(choose_OnMouseActivity); choosesc.KeyDown += new KeyEventHandler(MyKeyDown); choosesc.KeyPress += new KeyPressEventHandler(MyKeyPress); choosesc.KeyUp += new KeyEventHandler(MyKeyUp); public void MyKeyDown(object sender, KeyEventArgs e) { } public void MyKeyPress(object sender, KeyPressEventArgs e) { } public void MyKeyUp(object sender, KeyEventArgs e) { } void choose_OnMouseActivity(object sender, MouseEventArgs e) { if (e.Clicks > 0) { if ((MouseButtons)(e.Button) == MouseButtons.Left) { point[0] = e.Location; } if ((MouseButtons)(e.Button) == MouseButtons.Right) { point[1] = e.Location; } } //throw new Exception("The method or operation is not implemented."); }
C#监测全局键盘与鼠标事件
最新推荐文章于 2024-07-07 00:10:56 发布