纯C#钩子实现及应用
2011-11-03 10:06
225 查看
关于钩子
请参见微软中国社区中《HOOK专题》一文。
纯C#钩子(Hook)实现
要实现系统钩子其实很简单,调用三个Win32的API即可。
SetWindowsHookEx 用于设置钩子。(设立一道卡子,盘查需要的信息)
[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-屏幕放大器
点击下载可执行文件(Shift + Esc
退出程序) http://files.cnblogs.com/sharkoo/screenmagnifierexe.rar
点击下载源文件
http://files.cnblogs.com/sharkoo/screenmagnifier.rar
所谓屏幕放大器,类似与WINDOWS系统中的辅助工具中的放大镜。
前两天在找资料的时候突然发现在2.0中,Graphics类多了一个CopyFromScreen方法,可以直接实现屏幕抓取,于是有了做屏幕放大器的想法。
首先我定义了是SKHOOK类,来截取键盘及鼠标。
由于需要获得全局的鼠标消息来确定截屏位置,同时要建立一个全局的快捷键来退出程序,所以只能用上面说的钩子来实现。
然后我通过鼠标点来设置采样区域,以及窗体的位置。
采样区域为鼠标点为中心的50*50的矩形区域。窗体位置只实现了简单的鼠标跟随,同时保证了和采样区域不重叠。
另外我使用了一个BackgroundWorker来定时刷新更新窗体。主要是为了实现动画内容(GIF、Flash等)的显示。
至于移动的时候使用SetWindowPos,主要是为了保证窗体一直位于顶层,否则的话一些置顶的窗口(如QQ)等将覆盖当前窗口。
已知问题:
1。不支持视频截取
2。部分ToolTip提示无法显示
3。可能会造成背景窗口部分显示失效。
4。SKHook类中,对于键盘事件处理,存在不足。
还有一个问题,就是当鼠标移动比较快的时候,窗口边框会有残影,不知道是什么原因。这个问题在以往的Fram窗体中一直是困扰我的问题,至今没有找到解决的办法。
转载:http://sharkoo.cnblogs.com/archive/2006/03/27/357878.html
请参见微软中国社区中《HOOK专题》一文。
纯C#钩子(Hook)实现
要实现系统钩子其实很简单,调用三个Win32的API即可。
SetWindowsHookEx 用于设置钩子。(设立一道卡子,盘查需要的信息)
[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-屏幕放大器
点击下载可执行文件(Shift + Esc
退出程序) http://files.cnblogs.com/sharkoo/screenmagnifierexe.rar
点击下载源文件
http://files.cnblogs.com/sharkoo/screenmagnifier.rar
所谓屏幕放大器,类似与WINDOWS系统中的辅助工具中的放大镜。
前两天在找资料的时候突然发现在2.0中,Graphics类多了一个CopyFromScreen方法,可以直接实现屏幕抓取,于是有了做屏幕放大器的想法。
首先我定义了是SKHOOK类,来截取键盘及鼠标。
由于需要获得全局的鼠标消息来确定截屏位置,同时要建立一个全局的快捷键来退出程序,所以只能用上面说的钩子来实现。
然后我通过鼠标点来设置采样区域,以及窗体的位置。
采样区域为鼠标点为中心的50*50的矩形区域。窗体位置只实现了简单的鼠标跟随,同时保证了和采样区域不重叠。
另外我使用了一个BackgroundWorker来定时刷新更新窗体。主要是为了实现动画内容(GIF、Flash等)的显示。
至于移动的时候使用SetWindowPos,主要是为了保证窗体一直位于顶层,否则的话一些置顶的窗口(如QQ)等将覆盖当前窗口。
已知问题:
1。不支持视频截取
2。部分ToolTip提示无法显示
3。可能会造成背景窗口部分显示失效。
4。SKHook类中,对于键盘事件处理,存在不足。
还有一个问题,就是当鼠标移动比较快的时候,窗口边框会有残影,不知道是什么原因。这个问题在以往的Fram窗体中一直是困扰我的问题,至今没有找到解决的办法。
转载:http://sharkoo.cnblogs.com/archive/2006/03/27/357878.html
相关文章推荐
- 纯C#钩子实现及应用(转)
- WPF毫秒级桌面时钟的实现-C#中Hook(钩子)的应用
- 纯C#钩子实现及应用
- 纯C#钩子实现及应用
- 纯C#钩子实现及应用
- 【转载】遗传算法的C#实现及应用
- 非对称加密RSA的应用及在C#中的实现
- C# 实现WEBSOCKET聊天应用示例
- 非对称加密RSA的应用及在C#中的实现
- [导入]C#中应用PSFTP实现SFTP上传
- C#应用jstree实现无限级节点的方法
- [置顶]白话贝叶斯理论及在足球比赛结果预测中的应用和C#实现
- 第一页(服务端) :远程资源管理器 c#应用源代码,SERVICE + CLIENT 模式 可实现远程文件管理,下载功能
- TCP应用编程--套接字C#实现
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java) (转载)
- 用JPUSH极光推送实现服务端向安装了APP应用的手机推送消息(C#服务端接口)
- 有C#来实现WEB服务器的应用分析
- 数据结构与算法读书笔记6----C# Stack类实现与应用
- ASP.NET应用中用C#实现基于表单的认证
- C#开发微信门户及应用(31)--微信语义理解接口的实现和处理