友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

VC语言6.0程序设计从入门到精通-第77章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




并 且 在 窗 口 过 程 处 理 完 消 息 之 后 调 用 WH_CALLWNDPROCRET  Hook 子 程 。 

WH_CALLWNDPROCRET Hook 传递指针到 CWPRETSTRUCT 结构,再传递到 Hook 子程。 

CWPRETSTRUCT 结构包含了来自处理消息的窗口过程的返回值,同样也包括了与这个消息 

关联的消息参数。  



   (2 )WH_CBT Hook  

   在如下事件之前,系统都会调用 WH_CBT Hook 子程。    

   o  激活、建立、销毁、最小化、最大化、移动、改变尺寸等窗口事件。    

   o  完成系统指令。  

   o  来自系统消息队列中的移动鼠标、键盘事件。  

   o  设置输入焦点事件。  

   o  同步系统消息队列事件。    

   o  Hook 子程的返回值确定系统是否允许或者防止这些操作中的一个。  



                                                        ·271 ·  


…………………………………………………………Page 283……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



    (3 )WH_DEBUG Hook  

    在系统调用系统中与其他 Hook 关联的 Hook 子程之前,系统会调用 WH_DEBUG  Hook 

子程。可以使用这个 Hook 来决定是否允许系统调用与其他 Hook 关联的 Hook 子程。  



    (4 )WH_FOREGROUNDIDLE Hook  

    当应用程序的前台线程处于空闲状态时,可以使用 WH_FOREGROUNDIDLE Hook 执行 

低 优 先 级 的 任 务 。 当 应 用 程 序 的 前 台 线 程 要 变 成 空 闲 状 态 时 , 系 统 就 会 调 用 

WH_FOREGROUNDIDLE Hook 子程。  



    (5 )WH_GETMESSAGE Hook  

    应用程序用 WH_GETMESSAGE Hook 来监视从 GetMessage 或者 PeekMessage 函数返回 

的消息。可以使用 WH_GETMESSAGE  Hook 去监视鼠标和键盘输入,以及其他发送到消息 

队列中的消息。  



    (6 )WH_JOURNALPLAYBACK Hook  

    WH_JOURNALPLAYBACK  Hook 使应用程序可以插入消息到系统消息队列。可以使用 

该  Hook 回放用  WH_JOURNALRECORD  Hook    记录下来的连续的鼠标和键盘事件。只要 

WH_JOURNALPLAYBACK   Hook   已 经 安 装 , 正 常 的 鼠 标 和 键 盘 事 件 就 是 无 效 的 。 

WH_JOURNALPLAYBACK  Hook    是全局   Hook ,它不能像线程特定         Hook 一样使用。 

WH_JOURNALPLAYBACK Hook 返回超时值,这个值告诉系统在处理来自回放 Hook 当前消 

息 之 前 需 要 等 待 多 长 时 间 ( 毫 秒 )。 这 就 使     Hook 可 以 控 制 实 时 事 件 的 回 放 。 

WH_JOURNALPLAYBACK 是 system…wide local hooks,它们不会被映射到任何进程的地址空 

间中。  



    (7 )WH_JOURNALRECORD Hook  

    WH_JOURNALRECORD Hook 用来监视和记录输入事件。可以使用这个 Hook 记录连续的 

鼠 标 和 键 盘 事 件 , 然 后 通 过 使 用        WH_JOURNALPLAYBACK    Hook  来 回 放 。 

WH_JOURNALRECORD   Hook   是 全 局  Hook , 它 不 能 像 线 程 特 定  Hook 一 样 使 用 。 

WH_JOURNALRECORD 是 system…wide local hooks,它们不会被映射到任何进程的地址空 

间中。  



    (8)WH_KEYBOARD Hook  

    在应用程序中,WH_KEYBOARD  Hook 用来监视 WM_KEYDOWN 和 WM_KEYUP 消 

息,这些消息通过 GetMessage 或 PeekMessage  function 返回。可以用该 Hook 来监视输入到 

消息队列中的键盘消息。  



    (9 )WH_KEYBOARD_LL Hook  

    WH_KEYBOARD_LL Hook 监视输入到线程消息队列中的键盘消息。  



    (10)WH_MOUSE Hook  

    WH_MOUSE  Hook 监视从 GetMessage 或者 PeekMessage 函数中返回的鼠标消息。使用 

这个 Hook 监视输入到消息队列中的鼠标消息。  



    (11)WH_MOUSE_LL Hook  

    WH_MOUSE_LL Hook 监视输入到线程消息队列中的鼠标消息。  



 ·272 ·  


…………………………………………………………Page 284……………………………………………………………

                                                     第 10 章    动态链接库  



   (12)WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks  

   WH_MSGFILTER 和 WH_SYSMSGFILTER  Hooks 可以监视菜单、滚动条、消息框、对 

话框消息并且发现用户使用  ALT+TAB  或者  ALT+ESC  组合键切换窗口。WH_MSGFILTER  

Hook 只能监视传递到菜单、滚动条、消息框的消息,以及传递到通过安装了 Hook 子程的应 

用 程 序 建 立 的 对 话 框 的 消 息 。 WH_SYSMSGFILTER   Hook 监 视 所 有 应 用 程 序 消 息 。 

WH_MSGFILTER 和 WH_SYSMSGFILTER  Hooks 可以在模式循环期间过滤消息,这等价于 

在主消息循环中过滤消息。通过调用 CallMsgFilter  function 可以直接调用 WH_MSGFILTER  

Hook 。通过使用这个函数,应用程序能够在模式循环期间使用相同的代码去过滤消息,如同 

在主消息循环里一样。  



   (13)WH_SHELL Hook  

   外壳应用程序可以使用 WH_SHELL Hook 去接收重要的通知。当外壳应用程序为激活状 

态并且当顶层窗口建立或者销毁时,系统调用 WH_SHELL  Hook 子程。WH_SHELL 共有 5 

种情況:  

   o  只要有 top…level 、unowned 窗口被产生、起作用、或是被摧毁;    

   o  当 Taskbar 需要重画某个按钮;    

   o  当系统需要显示关于 Taskbar 的一个程序的最小化形式;    

   o  当目前的键盘布局状态改变;    

   o  当使用者按 Ctrl+Esc 去执行 Task Manager (或相同级别的程序)。  

   按照惯例,外壳应用程序都不接收             WH_SHELL  消息。所以在应用程序能够接收 

WH_SHELL 消息之前,应用程序必须调用 SystemParametersInfo function 注册它自己。  



   2 .按使用范围分类  



   按使用范围分类,主要有线程钩子和系统钩子。线程钩子监视指定线程的事件消息,系 

统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所 

                              DLL )中。  

以钩子函数必须放在独立的动态链接库( 

   o  如果对于同一事件(如鼠标消息)既安装了线程钩子又安装了系统钩子,那么系统会 

                                         

     自动先调用线程钩子,然后调用系统钩子。 

   o  对同一事件消息可安装多个钩子处理过程,这些钩子处理过程形成了钩子链。当前钩 

     子处理结束后应把钩子信息传递给下一个钩子函数。而且最近安装的钩子放在链的开 

     始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。    

   o  钩子特别是系统钩子会消耗消息处理时间,降低系统性能。只有在必要的时候才安装 

     钩子,在使用完毕后要及时卸载。  



10。7。2    使用钩子函数  



   使用钩子函数的程序的步骤分为定义钩子函数、安装钩子和卸载钩子这 3 步。下面详细 

介绍这 3 个过程。  



                                                              ·273 ·  


…………………………………………………………Page 285……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



    1.定义钩子函数  



   钩子函数是一种特殊的回调函数 。钩子监视的特定事件发生后,系统会调用钩子函数进 

行处理。不同事件的钩子函数的形式是各不相同的。下面以鼠标钩子函数举例说明钩子函数 

的原型:    



   LRESULT CALLBACK HookProc(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  是钩子函数。    

   也可以通过直接返回 TRUE 来丢弃该消息,阻止该消息的传递。  



   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  UnhookWindowsHook 

Ex(HHOOK hhk) 即可。  

   值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别 。线程钩子一般在当 

前线程或者当前线程派生的线程内,而系统钩子必须放在独立的动态链接库中,实现起来要 

麻烦一些。  



10。7。3    鼠标钩子应用实例  



实例 10…3:鼠标钩子应用实例。源代码在光盘中“10实例 10…3MouseHook”目录下。  



   本节通过一个鼠标钩子实例来介绍全局钩子的应用方法 。该实例的详细源代码请见附带 

光盘,其中 MouseHookDll  目录下的工程是全局鼠标钩子的实现动态链接库。MouseTest 工程 

通过调用 MouseHookDll  的动态链接库接口安装鼠标钩子并利用。在本例中鼠标钩子函数通 

过判断记录当前窗口的句柄来判断鼠标是否离开窗口边界,并将鼠标位置处的窗口名称实时 

地显示出来。  

   在  MouseHookDll 中实现全局钩子,首先是全局共享数据的实现。这里利用#pragma  



 ·274 ·  


…………………………………………………………Page 286……………………………………………………………

                                       
返回目录 上一页 下一页 回到顶部 0 1
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!