今天,有个同事问我,怎样在C#中使用全局钩子?以前写的全局钩子都是用unmanaged C或C++写个DLL来实现,可大家都知道,C#是基于.Net Framework的,是managed,怎么实现全局钩子呢?于是开始到网上搜索,好不容易找到一篇,318804 - HOW TO: Set a Windows Hook in Visual C# .NET,里面详细的说明了如何使用鼠标钩子捕获鼠标的移动等,可是,它只能在Application里起作用,出了Application就没用了,就是说它还是没有实现全局钩子,而且文章结尾处说:“Global Hooks are not supported in the .NET Framework...”,这可怎么办呢?
privateint MouseHookProc(int nCode, int wParam, IntPtr lParam) { // if ok and someone listens to our events if ((nCode >=0) && (OnMouseActivity !=null)) { //Marshall the data from callback. MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct)); //detect button clicked MouseButtons button = MouseButtons.None; short mouseDelta =0; switch (wParam) { case WM_LBUTTONDOWN: //case WM_LBUTTONUP: //case WM_LBUTTONDBLCLK: button = MouseButtons.Left; break; case WM_RBUTTONDOWN: //case WM_RBUTTONUP: //case WM_RBUTTONDBLCLK: button = MouseButtons.Right; break; case WM_MOUSEWHEEL: //If the message is WM_MOUSEWHEEL, the high-order word of mouseData member is the wheel delta. //One wheel click is defined as WHEEL_DELTA, which is 120. //(value >> 16) & 0xffff; retrieves the high-order word from the given 32-bit value mouseDelta = (short)((mouseHookStruct.mouseData >>16) &0xffff); //TODO: X BUTTONS (I havent them so was unable to test) //If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, //or WM_NCXBUTTONDBLCLK, the high-order word specifies which X button was pressed or released, //and the low-order word is reserved. This value can be one or more of the following values. //Otherwise, mouseData is not used. break; } //double clicks int clickCount =0; if (button != MouseButtons.None) if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount =2; else clickCount =1; //generate event MouseEventArgs e =new MouseEventArgs( button, clickCount, mouseHookStruct.pt.x, mouseHookStruct.pt.y, mouseDelta); //raise it OnMouseActivity(this, e); } //call next hook return CallNextHookEx(hMouseHook, nCode, wParam, lParam); }
privateint KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { //indicates if any of underlaing events set e.Handled flag bool handled =false; //it was ok and someone listens to events if ((nCode >=0) && (KeyDown !=null|| KeyUp !=null|| KeyPress !=null)) { //read structure KeyboardHookStruct at lParam KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); //raise KeyDown 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; } // raise KeyPress 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 =newbyte[256]; GetKeyboardState(keyState); byte[] inBuffer =newbyte[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; } } // raise KeyUp 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 event handled in application do not handoff to other listeners if (handled) return1; else return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); }
How to set a Windows hook in Visual C# .NET 如何在C#中使用全局鼠标、键盘Hook Posted on 2006-09-22 10:39 loose_went 阅读(758) 评论(19) 编辑 收藏 引用 网摘 所属分类: C# .Net <!--<rdf:RDF xmlns:rdf="http://www.w3.org/19