http://www.soasp.net/FilePage/200804/20080404132503.htm |
关于钩子
请参见微软中国社区中《HOOK专题》一文。 纯C#钩子(Hook)实现 要实现系统钩子其实很简单,调用三个Win32的API即可。 [DllImport( "user32.dll", CallingConvention = CallingConvention.StdCall )]
public static extern IntPtr SetWindowsHookEx ( WH_Codes idHook, HookProc lpfn, IntPtr pInstance, int threadId ); CallNextHookEx 用于传递钩子(消息是重要的,所以从哪里来,就应该回到哪里去,除非你决定要封锁消息) [DllImport( "user32.dll", CallingConvention = CallingConvention.StdCall )]
public static extern int CallNextHookEx ( IntPtr pHookHandle, int nCode, Int32 wParam, IntPtr lParam ); UnhookWindowsHookEx 卸载钩子(卸载很重要,卡子设多了会造成拥堵) [DllImport( "user32.dll", CallingConvention = CallingConvention.StdCall )]
public static extern bool UnhookWindowsHookEx ( IntPtr pHookHandle ); 在《HOW TO:在 Visual C# .NET 中设置窗口挂钩》一文中有如下描述: 在 .NET 框架中不支持全局挂钩
您无法在 Microsoft .NET 框架中实现全局挂钩。若要安装全局挂钩,挂钩必须有一个本机动态链接库 (DLL) 导出以便将其本身插入到另一个需要调入一个有效而且一致的函数的进程中。这需要一个 DLL 导出,而 .NET 框架不支持这一点。托管代码没有让函数指针具有统一的值这一概念,因为这些函数是动态构建的代理。 网上查找了很多代码,大都另外包含了一个C++的DLL,用于标识包含lpfn所指的子程的DLL,似乎也验证了这一说法。 IntPtr pInstance = Marshal.GetHINSTANCE( Assembly.GetExecutingAssembly().ManifestModule );
Win32API.SetWindowsHookEx( WH_MOUSE_LL,m_MouseHookProcedure, pInstance, 0 ); 注:ManifestModule属性是.Net Framework 2.0中新增加的,所以当你依然使用.Net Framework 1.x的时候,可以使用GetModules方法获取当前程序集的所有模块,然后用其中的一个作为GetHINSTAN方法的参数,来获得合适的句柄指针。 钩子应用DEMO-屏幕放大器 所谓屏幕放大器,类似与WINDOWS系统中的辅助工具中的放大镜。 首先我定义了是SKHOOK类,来截取键盘及鼠标。 然后我通过鼠标点来设置采样区域,以及窗体的位置。 另外我使用了一个BackgroundWorker来定时刷新更新窗体。主要是为了实现动画内容(GIF、Flash等)的显示。 已知问题: 还有一个问题,就是当鼠标移动比较快的时候,窗口边框会有残影,不知道是什么原因。这个问题在以往的Fram窗体中一直是困扰我的问题,至今没有找到解决的办法。 |