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

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

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




   外壳应用程序可以使用 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……………………………………………………………

                                                                                        第 10 章    动态链接库  



data_seg 建立一个新的数据段并定义共享数据,其具体格式为:  



     pragma data_seg (〃shareddata〃)  



      HWND sharedwnd=NULL;//共享数据      



      #pragma data_seg()  



      所有在 data_seg pragmas 语句之间声明的变量都将在 shareddata 段中。仅定义一个数据段 

还不能达到共享数据的目的,还要告诉编译器该段的属性,有两种方法可以实现该目的(其 

效果是相同的),一种方法是在 DEF 文件中加入如下语句:  



      SETCTIONS  



      shareddata READ WRITE SHARED  



      另一种方法是在项目设置链接选项中加入如下语句:  



     /SECTION:shareddata;rws  



      MouseHookDll 是一个 MFC 扩展动态链接库,其中包含的安装钩子和卸载钩子的全局函 

数如下:  



      BOOL __stdcall StartHook(HWND hwnd);  



       



      BOOL __stdcall StopHook();  



      全局共享数据声明如下:  



      #pragma data_seg(〃mydata〃)      



      HWND glhPrevTarWnd=NULL;               //上次鼠标所指的窗口句柄      



      HWND glhDisplayWnd=NULL;               //显示目标窗口标题编辑框的句柄      



      HHOOK glhHook=NULL;                    //安装的鼠标勾子句柄      



      HINSTANCE glhInstance=NULL;            //DLL 实例句柄      



      #pragma data_seg()  



      在 DEF 文件中加入如下定义:  



      SECTIONS  



     mydata READ WRITE SHARED  



      在主文件 MouseHookDll。cpp 的 DllMain() 函数中加入保存 DLL 实例句柄的语句如下:  



      extern 〃C〃 int APIENTRY      



      DllMain(HINSTANCE hInstance; DWORD dwReason; LPVOID lpReserved)    



      {    



           UNREFERENCED_PARAMETER(lpReserved);    



           if (dwReason == DLL_PROCESS_ATTACH)    



           {    



                 if (!AfxInitExtensionModule(MouseHookDLL; hInstance))    



                      return 0;    



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