利用勾子监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理

   钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定  
  的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得  
  到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传  
  递该消息,还可以强制结束消息的传递。对每种类型的钩子由系统来维护一个钩子链  
  ,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的先获  
  得控制权。要实现Win32的系统钩子,必须调用SDK中的API函数SetWindowsHookEx来  
  安装这个钩子函数,这个函数的原型是HHOOK   SetWindowsHookEx(int    
  idHook,HOOKPROC   lpfn,HINSTANCE   hMod,DWORD   dwThreadId);,其中,第一个参数是  
  钩子的类型;第二个参数是钩子函数的地址;第三个参数是包含钩子函数的模块句柄  
  ;第四个参数指定监视的线程。如果指定确定的线程,即为线程专用钩子;如果指定  
  为空,即为全局钩子。其中,全局钩子函数必须包含在DLL(动态链接库)中,而线  
  程专用钩子还可以包含在可执行文件中。得到控制权的钩子函数在完成对消息的处理  
  后,如果想要该消息继续传递,那么它必须调用另外一个SDK中的API函数  
  CallNextHookEx来传递它。钩子函数也可以通过直接返回TRUE来丢弃该消息,并阻止  
  该消息的传递。


通常消息都是停留在消息队列中等待被隶属的窗口抓取,  
  设立钩子hook,就可以更早一步抓取消息,  
  并且可以抓取不属于你的消息,  
  送往你设定的所谓“滤网函数(filter)”。  
   
  什么是勾子    
   
  ----   在Windows系统中,勾子(hook)是一种特殊的消息处理机制。勾子可以监视系统或    
   
  进程中的各种事件消息,截获发往目标窗口的消息并进行处理。这样,我们就可以在系    
   
  统中安装自定义的勾子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘    
   
  、鼠标的输入,屏幕取词,日志监视等等。可见,利用勾子可以实现许多特殊而有用的    
   
  功能。因此,对于高级编程人员来说,掌握勾子的编程方法是很有必要的。    
   
  勾子的类型    
   
  ----1.   按事件分类,有如下的几种常用类型    
   
  ----(1)   键盘勾子和低级键盘勾子可以监视各种键盘消息。    
   
  ----(2)   鼠标勾子和低级鼠标勾子可以监视各种鼠标消息。    
   
  ----(3)   外壳勾子可以监视各种Shell事件消息。比如启动和关闭应用程序。    
   
  ----(4)   日志勾子可以记录从系统消息队列中取出的各种事件消息。    
   
  ----(5)   窗口过程勾子监视所有从系统消息队列发往目标窗口的消息。    
   
  ----此外,还有一些特定事件的勾子提供给我们使用,不一一列举。    
   
  ----2.   按使用范围分类,主要有线程勾子和系统勾子    
   
  ----(1)   线程勾子监视指定线程的事件消息。    
   
  ----(2)   系统勾子监视系统中的所有线程的事件消息。因为系统勾子会影响系统中所    
   
  有的应用程序,所以勾子函数必须放在独立的动态链接库(DLL)   中。这是系统勾子和线    
   
  程勾子很大的不同之处。    
   
  ----   几点需要说明的地方:    
   
  ----(1)   如果对于同一事件(如鼠标消息)既安装了线程勾子又安装了系统勾子,那    
   
  么系统会自动先调用线程勾子,然后调用系统勾子。    
   
  ----(2)   对同一事件消息可安装多个勾子处理过程,这些勾子处理过程形成了勾子链    
   
  。当前勾子处理结束后应把勾子信息传递给下一个勾子函数。    
   
  ----(3)   勾子特别是系统勾子会消耗消息处理时间,降低系统性能。只有在必要的时    
   
  候才安装勾子,在使用完毕后要及时卸载。    
   
  编写勾子程序    
   
  ----   编写勾子程序的步骤分为三步:定义勾子函数、安装勾子和   对   勾子。    
   
  ----1.定义勾子函数    
   
  ----勾子函数是一种特殊的回调函数。勾子监视的特定事件发生后,系统会调用勾子函    
   
  数进行处理。不同事件的勾子函数的形式是各不相同的。下面以鼠标勾子函数举例说明    
   
  勾子函数的原型:    
   
  LRESULT   CALLBACK   MouseProc    
   
  (     int   nCode,   WPARAM   wParam,   LPARAM   lParam)    
   
  ----参数wParam和   lParam包含鼠标消息的信息,比如鼠标位置、状态等。nCode包含有    
   
  关消息本身的信息,比如是否从消息队列中移出。    
   
  ----   我们先在勾子函数中实现自定义的功能,然后调用函数   CallNextHookEx.把勾子信    
   
  息传递给勾子链的下一个勾子函数。CallNextHookEx.的原型如下:    
   
  LRESULT   CallNextHookEx    
   
  (   HHOOK   hhk,     int   nCode,    
   
  WPARAM   wParam,   LPARAM   lParam    
   
  ----参数   hhk是勾子句柄。nCode、wParam和lParam   是勾子函数。下面的例子是一个简    
   
  单的监视鼠标消息的勾子函数:    
   
  LRESULT   CALLBACK     MouseProc    
   
  (int   nCode,   WPARAM   wParam,   LPARAM   lParam)    
   
  {    
   
  //跟踪鼠标移动时的位置变化信息    
   
  if(wParam==WM_MOUSEMOVE   ¦¦   wParam==    
   
                      WM_NCMOUSEMOVE)    
   
  {   //是鼠标移动消息    
   
  point=((MOUSEHOOKSTRUCT   *)    
   
  lParam)->pt;//取鼠标信息    
   
  TRACE2(“Position   is   :%d,Y:%d/n",point.x,point.y);    
   
  }    
   
  //传递勾子信息    
   
  return   CallNextHookEx(hHook,nCode,wParam,lParam);    
   
  }    
   
  ----2.安装勾子    
   
  ----在程序初始化的时候,调用函数SetWindowsHookEx安装勾子。其函数原型为:    
   
  HHOOK   SetWindowsHookEx    
   
  (   int   idHook,HOOKPROC   lpfn,    
   
  INSTANCE   hMod,DWORD   dwThreadId    
   
  ----参数idHook表示勾子类型,它是和勾子函数类型一一对应的。比如,WH_KEYBOARD表    
   
  示安装的是键盘勾子,WH_MOUSE表示是鼠标勾子等等。    
   
  ----Lpfn是勾子函数的地址。    
   
  ----HMod是勾子函数所在的实例的句柄。对于线程勾子,该参数为NULL;对于系统勾子    
   
  ,该参数为勾子函数所在的DLL句柄。    
   
  ----   dwThreadId   指定勾子所监视的线程的线程号。对于全局勾子,该参数为NULL。    
   
  ----SetWindowsHookEx返回所安装的勾子句柄。    
   
  ----3.   对   勾子    
   
  ----   当不再使用勾子时,必须及时卸载。简单地调用函数   BOOL   UnhookWindowsHookEx    
   
  (   HHOOK   hhk)即可。    
   
  ----   值得注意的是线程勾子和系统勾子的勾子函数的位置有很大的差别。线程勾子一般    
   
  在当前线程或者当前线程派生的线程内,而系统勾子必须放在独立的动态链接库中,实    
   
  现起来要麻烦一些。    
   
  线程勾子的编程实例    
   
  ----按照上面介绍的方法实现一个线程级的鼠标勾子。勾子跟踪当前窗口鼠标移动的位    
   
  置变化信息。并输出到窗口。    
   
  ----(1)在VC++6.0中利用MFC   APPWizard(EXE)生成一个不使用文档/视结构的单文档    
   
  应用mousehook。打开childview.cpp文件,加入全局变量:    
   
  HHOOK   hHook;//鼠标勾子句柄    
   
  CPoint   point;//鼠标位置信息    
   
  CChildView   

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值