(转贴)纯C#钩子(Hook)实现

 

关于钩子
请参见微软中国社区中《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 退出程序)
点击下载源文件

所谓屏幕放大器,类似与WINDOWS系统中的辅助工具中的放大镜。
前两天在找资料的时候突然发现在2.0中,Graphics类多了一个CopyFromScreen方法,可以直接实现屏幕抓取,于是有了做屏幕放大器的想法。

首先我定义了是SKHOOK类,来截取键盘及鼠标。
由于需要获得全局的鼠标消息来确定截屏位置,同时要建立一个全局的快捷键来退出程序,所以只能用上面说的钩子来实现。

然后我通过鼠标点来设置采样区域,以及窗体的位置。
采样区域为鼠标点为中心的50*50的矩形区域。窗体位置只实现了简单的鼠标跟随,同时保证了和采样区域不重叠。

另外我使用了一个BackgroundWorker来定时刷新更新窗体。主要是为了实现动画内容(GIF、Flash等)的显示。

至于移动的时候使用SetWindowPos,主要是为了保证窗体一直位于顶层,否则的话一些置顶的窗口(如QQ)等将覆盖当前窗口。

已知问题:
1。不支持视频截取
2。部分ToolTip提示无法显示
3。可能会造成背景窗口部分显示失效。
4。SKHook类中,对于键盘事件处理,存在不足。

还有一个问题,就是当鼠标移动比较快的时候,窗口边框会有残影,不知道是什么原因。这个问题在以往的Fram窗体中一直是困扰我的问题,至今没有找到解决的办法。
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C是一种计算机编程语言,由美国贝尔实验室的丹尼斯·里奇于1972年开发。C语言是一种通用的高级程序设计语言,被广泛应用于系统软件、应用软件和嵌入式系统的开发中。 C语言的设计目标是提供高效、可移植和可扩展的编程环境。它具有较低的级别和较高的抽象程度,允许程序员直接访问和操作计算机硬件,同时具备更高级别语言的表达能力。 C语言具有简洁而又灵活的语法结构,使得程序员可以轻松地编写和理解代码。它支持丰富的数据类型、运算符和控制流结构,为程序员提供了强大的编程能力。同时,C语言还提供了丰富的库函数,使得编写复杂的程序变得更加简单。 C语言的特点之一是具有良好的可移植性。由于C语言在不同的计算机系统上的实现较为统一,因此编写的程序可以很容易地在不同的平台上运行。这使得C语言成为了跨平台开发的首选语言。 C语言的应用非常广泛。它被用于开发各种类型的软件,包括操作系统、编译器、数据库、网络协议等。此外,C语言还被广泛应用于嵌入式系统的开发中,因为它能够直接访问硬件资源,具备较好的性能和效率。 总之,C语言是一种功能强大、灵活且可移植的编程语言。它在计算机科学领域发挥着重要的作用,无论是在系统软件还是应用软件的开发中,都有着广泛的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值