c#使用钩子拦截鼠标键盘事件
生活随笔
收集整理的這篇文章主要介紹了
c#使用钩子拦截鼠标键盘事件
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
窗體本身帶的鍵盤鼠標(biāo)事件函數(shù)只能響應(yīng)窗體自己的事件,窗體之外的事件是不會(huì)響應(yīng)的。比如當(dāng)窗體最小化的時(shí)候也響應(yīng)就要用全局鉤子攔截消息來處理了。
大概過程就是在窗體初始化時(shí)加載鉤子,等待事件消息,事件觸發(fā)后調(diào)用響應(yīng)函數(shù)處理。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; //DllImport名空間 using System.Windows.Forms; //MouseEventHandler名空間 using System.Reflection; //Assembly名空間 using System.ComponentModel; //Win32Exception名空間 using System.Diagnostics;//PROCESS命名空間namespace ShieldKeyBoardTouch {class MouseKeyHook{[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;}[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);[DllImport("kernel32.dll", EntryPoint = "GetModuleHandleA", SetLastError = true, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true)]public static extern IntPtr GetModuleHandleA(String lpModuleName);[DllImport("kernel32.dll", EntryPoint = "GetModuleHandleW", SetLastError = true, CharSet = CharSet.Unicode, ThrowOnUnmappableChar = true)]public static extern IntPtr GetModuleHandleW(String lpModuleName);//消息參數(shù)的值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;public MouseKeyHook(){Start();}public MouseKeyHook(bool InstallMouseHook, bool InstallKeyboardHook){Start(InstallMouseHook, InstallKeyboardHook);}~MouseKeyHook(){Stop(true, true, false);}public event MouseEventHandler OnMouseActivity; //MouseEventHandler是委托,表示處理窗體、控件或其他組件的 MouseDown、MouseUp 或 MouseMove 事件的方法。public event KeyEventHandler KeyDown;public event KeyPressEventHandler KeyPress;public event KeyEventHandler KeyUp;private int hMouseHook = 0; //標(biāo)記mouse hook是否安裝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){IntPtr HM = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);if (hMouseHook == 0 && InstallMouseHook){MouseHookProcedure = new HookProc(MouseHookProc);//鉤子的處理函數(shù)hMouseHook = SetWindowsHookEx(WH_MOUSE_LL,MouseHookProcedure,GetModuleHandleW(Process.GetCurrentProcess().MainModule.ModuleName),//本進(jìn)程模塊句柄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]),GetModuleHandleW(Process.GetCurrentProcess().MainModule.ModuleName),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;int clickCount = 0;switch (wParam){case WM_LBUTTONDOWN://513出現(xiàn)了button = MouseButtons.Left;clickCount = 1;break;case WM_RBUTTONDOWN://516出現(xiàn)了button = MouseButtons.Right;clickCount = 1;break;case WM_LBUTTONDBLCLK://515 ?doubleclick沒有出現(xiàn)過button = MouseButtons.XButton1;clickCount = 2;break;case WM_RBUTTONDBLCLK://518button = MouseButtons.XButton1;clickCount = 2;break;case WM_MOUSEMOVE://512?出現(xiàn)了button = MouseButtons.XButton2;clickCount = 0;break;case WM_MOUSEWHEEL://522?沒試mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff);clickCount = 0;break;} MouseEventArgs e = new MouseEventArgs(button,clickCount,mouseHookStruct.pt.x,mouseHookStruct.pt.y,mouseDelta);OnMouseActivity(this, e);//轉(zhuǎn)給委托函數(shù)}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); //轉(zhuǎn)給委托函數(shù)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;elsereturn CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);}} }這個(gè)類是用來加載鉤子的,然后在窗體中定義委托函數(shù),我只用了keydown和OnMouseActivity,讓窗體本身的事件相應(yīng)函數(shù)來處理它們。也可以自己另外寫函數(shù)處理
public partial class Form1 : Form{private MouseKeyHook mouseKeyHook1 = new MouseKeyHook(true,true);//鼠標(biāo),鍵盤public Form1(){InitializeComponent();mouseKeyHook1.KeyDown += new KeyEventHandler(Form1_KeyDown);//mouseKeyHook1.KeyPress += new KeyPressEventHandler(mouseKeyHook1_KeyPress);//mouseKeyHook1.KeyUp += new KeyEventHandler(mouseKeyHook1_KeyUp);mouseKeyHook1.OnMouseActivity += new MouseEventHandler(Form1_MouseDown);} }private void Form1_KeyDown(object sender, KeyEventArgs e){//MessageBox.Show("key down ", "message:", MessageBoxButtons.OK);LogFileCotent = LogFileCotent + "key down at : " + DateTime.Now.ToString() + " fail\r\n";textBox1.AppendText("key down at : " + DateTime.Now.ToString());textBox1.AppendText(Environment.NewLine);}
還有一個(gè)問題就是鼠標(biāo)消息其實(shí)沒有出現(xiàn)DOUBECLICK的值?,原因應(yīng)該也是click在前面被它取代了。解決的辦法是利用timer計(jì)時(shí)兩次click時(shí)間差,功能得自己寫。
總結(jié)
以上是生活随笔為你收集整理的c#使用钩子拦截鼠标键盘事件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AMD Opteron
- 下一篇: 电阻应变片式测力传感器弹性体设计要求