﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-iniwf-随笔分类-Hook</title><link>http://www.cppblog.com/iniwf/category/9838.html</link><description>风是温柔的，雨是伤心的，云是快乐的，月是多情的，爱是迷失的，恋是醉人的，情是难忘的，天是长久的，地是永恒的</description><language>zh-cn</language><lastBuildDate>Mon, 19 Apr 2010 09:52:11 GMT</lastBuildDate><pubDate>Mon, 19 Apr 2010 09:52:11 GMT</pubDate><ttl>60</ttl><item><title>钩子函数教程</title><link>http://www.cppblog.com/iniwf/archive/2010/04/14/112529.html</link><dc:creator>iniwf</dc:creator><author>iniwf</author><pubDate>Wed, 14 Apr 2010 02:11:00 GMT</pubDate><guid>http://www.cppblog.com/iniwf/archive/2010/04/14/112529.html</guid><wfw:comment>http://www.cppblog.com/iniwf/comments/112529.html</wfw:comment><comments>http://www.cppblog.com/iniwf/archive/2010/04/14/112529.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iniwf/comments/commentRss/112529.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iniwf/services/trackbacks/112529.html</trackback:ping><description><![CDATA[<p>转：<br></p>
<p>Windows系统是建立在事件驱动的机制上的，说穿了就是整个系统都是通过消息的传递来实现的。而钩子是Windows系统中非常重要的系统接 口，用它可以截获并处理送给其他应用程序的消息，来完成普通应用程序难以实现的功能。钩子可以监视系统或进程中的各种事件消息，截获发往目标窗口的消息并 进行处理。这样，我们就可以在系统中安装自定义的钩子，监视系统中特定事件的发生，完成特定的功能，比如截获键盘、鼠标的输入，屏幕取词，日志监视等等。 可见，利用钩子可以实现许多特殊而有用的功能。因此，对于高级编程人员来说，掌握钩子的编程方法是很有必要的。 </p>
<p>钩子的类型 <br>　　 一． 按事件分类，有如下的几种常用类型 <br>　　 （1） 键盘钩子和低级键盘钩子可以监视各种键盘消息。 <br>　　 （2） 鼠标钩子和低级鼠标钩子可以监视各种鼠标消息。 <br>　　 （3） 外壳钩子可以监视各种Shell事件消息。比如启动和关闭应用程序。 <br>　　 （4） 日志钩子可以记录从系统消息队列中取出的各种事件消息。 <br>　　 （5） 窗口过程钩子监视所有从系统消息队列发往目标窗口的消息。 <br>　　 此外，还有一些特定事件的钩子提供给我们使用，不一一列举。 <br>下面描述常用的Hook类型： <br>1、WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks <br>WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks使你可以监视发送到窗口过程的消息。系统在消息发送到接收窗口过程之前调用WH_CALLWNDPROC Hook子程，并且在窗口过程处理完消息之后调用WH_CALLWNDPRO <br>CRET Hook子程。WH_CALLWNDPROCRET Hook传递指针到CWPRETSTRUCT结构，再传递到Hook子程。CWPRETSTRUCT结构包含了来自处理消息的窗口过程的返回值，同样也包括了与这个消息关联的消息参数。 </p>
<p>2、WH_CBT Hook <br>在以下事件之前，系统都会调用WH_CBT Hook子程，这些事件包括： <br>1. 激活，建立，销毁，最小化，最大化，移动，改变尺寸等窗口事件； <br>2. 完成系统指令； <br>3. 来自系统消息队列中的移动鼠标，键盘事件； <br>4. 设置输入焦点事件； <br>5. 同步系统消息队列事件。 <br>Hook子程的返回值确定系统是否允许或者防止这些操作中的一个。 <br>3、WH_DEBUG Hook <br>在系统调用系统中与其他Hook关联的Hook子程之前，系统会调用WH_DEBUG Hook子程。你可以使用这个Hook来决定是否允许系统调用与其他Hook关联的Hook子程。 <br>4、WH_FOREGROUNDIDLE Hook <br>当应用程序的前台线程处于空闲状态时，可以使用WH_FOREGROUNDIDLE Hook执行低优先级的任务。当应用程序的前台线程大概要变成空闲状态时，系统就会调用WH_FOREGROUNDIDLE Hook子程。 <br>5、WH_GETMESSAGE Hook <br>应用程序使用WH_GETMESSAGE Hook来监视从GetMessage or PeekMessage函数返回的消息。你可以使用WH_GETMESSAGE Hook去监视鼠标和键盘输入，以及其他发送到消息队列中的消息。 <br>6、WH_JOURNALPLAYBACK Hook <br>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，它們不會被注射到任何行程位址空間。（估计按键精灵是用这个hook做的） <br>7、WH_JOURNALRECORD Hook <br>WH_JOURNALRECORD Hook用来监视和记录输入事件。典型的，可以使用这个Hook记录连续的鼠标和键盘事件，然后通过使用WH_JOURNALPLAYBACK Hook来回放。WH_JOURNALRECORD Hook是全局Hook，它不能象线程特定Hook一样使用。WH_JOURNALRECORD是system-wide local hooks，它們不會被注射到任何行程位址空間。 <br>8、WH_KEYBOARD Hook <br>在应用程序中，WH_KEYBOARD Hook用来监视WM_KEYDOWN and WM_KEYUP消息，这些消息通过GetMessage or PeekMessage function返回。可以使用这个Hook来监视输入到消息队列中的键盘消息。 <br>9、WH_KEYBOARD_LL Hook <br>WH_KEYBOARD_LL Hook监视输入到线程消息队列中的键盘消息。 <br>10、WH_MOUSE Hook <br>WH_MOUSE Hook监视从GetMessage 或者 PeekMessage 函数返回的鼠标消息。使用这个Hook监视输入到消息队列中的鼠标消息。 <br>11、WH_MOUSE_LL Hook <br>WH_MOUSE_LL Hook监视输入到线程消息队列中的鼠标消息。 <br>12、WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks <br>WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以监视菜单，滚动条，消息框，对话框消息并且发现用户使用ALT+TAB or ALT+ESC 组合键切换窗口。WH_MSGFILTER Hook只能监视传递到菜单，滚动条，消息框的消息，以及传递到通过安装了Hook子程的应用程序建立的对话框的消息。WH_SYSMSGFILTER Hook监视所有应用程序消息。WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以在模式循环期间过滤消息，这等价于在主消息循环中过滤消息。通过调用CallMsgFilter function可以直接的调用WH_MSGFILTER Hook。通过使用这个函数，应用程序能够在模式循环期间使用相同的代码去过滤消息，如同在主消息循环里一样。 <br>13、WH_SHELL Hook </p>
<p><br>外壳应用程序可以使用WH_SHELL Hook去接收重要的通知。当外壳应用程序是激活的并且当顶层窗口建立或者销毁时，系统调用WH_SHELL Hook子程。 <br>WH_SHELL 共有５钟情況： <br>1. 只要有个top-level、unowned 窗口被产生、起作用、或是被摧毁； <br>2. 当Taskbar需要重画某个按钮； <br>3. 当系统需要显示关于Taskbar的一个程序的最小化形式； <br>4. 当目前的键盘布局状态改变； <br>5. 当使用者按Ctrl+Esc去执行Task Manager（或相同级别的程序）。 <br>按照惯例，外壳应用程序都不接收WH_SHELL消息。所以，在应用程序能够接收WH_SHELL消息之前，应用程序必须调用SystemParametersInfo function注册它自己。 <br>以上是13种常用的hook类型！ <br>　　 二． 按使用范围分类，主要有线程钩子和系统钩子 <br>　　 （1） 线程钩子监视指定线程的事件消息。 <br>　　 （2） 系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序，所以钩子函数必须放在独立的动态链接库(DLL) <br>中。这是系统钩子和线程钩子很大的不同之处。 <br>　　 几点需要说明的地方： <br>　　 （1） 如果对于同一事件（如鼠标消息）既安装了线程钩子又安装了系统钩子，那么系统会自动先调用线程钩子，然后调用系统钩子。 <br>　　 （2） 对同一事件消息可安装多个钩子处理过程，这些钩子处理过程形成了钩子链。当前钩子处理结束后应把钩子信息传递给下一个钩子函数。而且最近安装的钩子放在链的开始，而最早安装的钩子放在最后，也就是后加入的先获得控制权。 <br>　　 （3） 钩子特别是系统钩子会消耗消息处理时间，降低系统性能。只有在必要的时候才安装钩子，在使用完毕后要及时卸载。 <br>编写钩子程序 </p>
<p><br>编写钩子程序的步骤分为三步：定义钩子函数、安装钩子和卸载钩子。 <br>　　 1．定义钩子函数 <br>　　 钩子函数是一种特殊的回调函数。钩子监视的特定事件发生后，系统会调用钩子函数进行处理。不同事件的钩子函数的形式是各不相同的。下面以鼠标钩子函数举例说明钩子函数的原型： <br>LRESULT CALLBACK HookProc(int nCode ,WPARAM wParam,LPARAM lParam) <br>参数wParam和 lParam包含所钩消息的信息，比如鼠标位置、状态，键盘按键等。nCode包含有关消息本身的信息，比如是否从消息队列中移出。 <br>我们先在钩子函数中实现自定义的功能，然后调用函数 CallNextHookEx.把钩子信息传递给钩子链的下一个钩子函数。CallNextHookEx.的原型如下： <br>LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam ) <br>参数 hhk是钩子句柄。nCode、wParam和lParam 是钩子函数。 <br>当然也可以通过直接返回TRUE来丢弃该消息，就阻止了该消息的传递。 <br>2．安装钩子 <br>　　 在程序初始化的时候，调用函数SetWindowsHookEx安装钩子。其函数原型为： <br>HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCE hMod,DWORD dwThreadId ) <br>参数idHook表示钩子类型，它是和钩子函数类型一一对应的。比如，WH_KEYBOARD表示安装的是键盘钩子，WH_MOUSE表示是鼠标钩子等等。 <br>　　 Lpfn是钩子函数的地址。 <br>　　 HMod是钩子函数所在的实例的句柄。对于线程钩子，该参数为NULL；对于系统钩子，该参数为钩子函数所在的DLL句柄。 <br>　　 dwThreadId 指定钩子所监视的线程的线程号。对于全局钩子，该参数为NULL。 <br>　　 SetWindowsHookEx返回所安装的钩子句柄。 <br>　　 3．卸载钩子 <br>　　 当不再使用钩子时，必须及时卸载。简单地调用函数 BOOL UnhookWindowsHookEx( HHOOK hhk)即可。 </p>
<p>值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别。线程钩子一般在当前线程或者当前线程派生的线程内，而系统钩子必须放在独立的动态链接库中，实现起来要麻烦一些。 </p>
<p>线程钩子的编程实例： <br>　　 按照上面介绍的方法实现一个线程级的鼠标钩子。钩子跟踪当前窗口鼠标移动的位置变化信息。并输出到窗口。 <br>　　 (1)在VC＋＋6.0中利用MFC <br>APPWizard（EXE）生成一个不使用文档/视结构的单文档应用mousehook。打开childview.cpp文件，加入全局变量： <br>HHOOK hHook;//鼠标钩子句柄 <br>CPoint point;//鼠标位置信息 <br>CChildView ＊pView; <br>// 鼠标钩子函数用到的输出窗口指针 </p>
<p>　　 在CChildView::OnPaint()添加如下代码： <br>CPaintDC dc(this); <br>char str[256]; <br>sprintf(str,&#8220;x=％d,y=％d",point.x,point.y); <br>//构造字符串 <br>dc.TextOut(0,0,str); //显示字符串 </p>
<p>　　 (2)childview.cpp文件中定义全局的鼠标钩子函数。 <br>LRESULT CALLBACK MouseProc <br>(int nCode, WPARAM wParam, LPARAM lParam) <br>{//是鼠标移动消息 <br>if(wParam==WM_MOUSEMOVE||wParam <br>==WM_NCMOUSEMOVE) <br>{ <br>point=((MOUSEHOOKSTRUCT ＊)lParam)－&gt;pt; <br>//取鼠标信息 <br>pView－&gt;Invalidate(); //窗口重画 <br>} <br>return CallNextHookEx(hHook,nCode,wParam,lParam); <br>//传递钩子信息 <br>} <br>(3)CChildView类的构造函数中安装钩子。 <br>CChildView::CChildView() <br>{ <br>pView=this;//获得输出窗口指针 <br>hHook=SetWindowsHookEx(WH_MOUSE,MouseProc,0,</p>
<p>GetCurrentThreadId()); <br>} <br>(4)CChildView类的析构函数中卸载钩子。 <br>CChildView::～CChildView() <br>{ <br>if(hHook) <br>UnhookWindowsHookEx(hHook); <br>} </p>
<p><br>系统钩子的编程实例： <br>由于系统钩子要用到dll，所以先介绍下win32 dll的特点： <br>Win32 DLL与 Win16 DLL有很大的区别，这主要是由操作系统的设计思想决定的。一方面，在Win16 DLL中程序入口点函数和出口点函数（LibMain和WEP）是分别实现的；而在Win32 DLL中却由同一函数DLLMain来实现。无论何时，当一个进程或线程载入和卸载DLL时，都要调用该函数，它的原型是BOOL WINAPI DllMain <br>(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);，其中，第一个参数表示DLL的实例句柄；第三个参数系统保留；这里主要介绍一下第二个参数，它有四个可能的 值：DLL_PROCESS_ATTACH（进程载入），DLL_THREAD_ATTACH（线程载入），DLL_THREAD_DETACH（线程卸 载），DLL_PROCESS_DETACH（进程卸载），在DLLMain函数中可以对传递进来的这个参数的值进行判别，并根据不同的参数值对DLL进 行必要的初始化或清理工作。举个例子来说，当有一个进程载入一个DLL时，系统分派给DLL的第二个参数为DLL_PROCESS_ATTACH，这时， 你可以根据这个参数初始化特定的数据。另一方面，在Win16环境下，所有应用程序都在同一地址空间；而在Win32环境下，所有应用程序都有自己的私有 空间，每个进程的空间都是相互独立的，这减少了应用程序间的相互影响，但同时也增加了编程的难度。大家知道，在Win16环境中，DLL的全局数据对每个 载入它的进程来说都是相同的；而在Win32环境中，情况却发生了变化，当进程在载入DLL时，系统自动把DLL地址映射到该进程的私有空间，而且也复制 该DLL的全局数据的一份拷贝到该进程空间，也就是说每个进程所拥有的相同的DLL的全局数据其值却并不一定是相同的。因此，在Win32环境下要想在多 个进程中共享数据，就必须进行必要的设置。亦即把这些需要共享的数据分离出来，放置在一个独立的数据段里，并把该段的属性设置为共享。 <br>在 VC6中有三种形式的MFC DLL（在该DLL中可以使用和继承已有的MFC类)可供选择，即Regular statically linked to MFC DLL（标准静态链接MFC DLL）和Regular using the shared MFC DLL（标准动态链接MFC DLL）以及Extension MFC DLL（扩展MFC DLL）。第一种DLL的特点是，在编译时把使用的MFC代码加入到DLL中，因此，在使用该程序时不需要其他MFC动态链接类库的存在，但占用磁盘空间 比较大；第二种DLL的特点是，在运行时，动态链接到MFC类库，因此减少了空间的占用，但是在运行时却依赖于MFC动态链接类库；这两种DLL既可以被 MFC程序使用也可以被Win32程序使用。第三种DLL的特点类似于第二种，做为MFC类库的扩展，只能被MFC程序使用。 <br>下面说说在VC6中全局共享数据的实现 <br>　　 在主文件中，用#pragma data_seg建立一个新的数据段并定义共享数据，其具体格式为： <br>　　 #pragma data_seg （"shareddata") <br>　　 HWND sharedwnd=NULL;//共享数据 <br>　　 #pragma data_seg() <br>　　 仅定义一个数据段还不能达到共享数据的目的，还要告诉编译器该段的属性，有两种方法可以实现该目的（其效果是相同的），一种方法是在.DEF文件中加入如下语句： <br>SETCTIONS shareddata READ WRITE SHARED <br>　　 另一种方法是在项目设置链接选项中加入如下语句： <br>　　 /SECTION:shareddata,rws <br>好了，准备知识已经学完了，让我们开始编写个全局的钩子程序吧！ </p>
<p><br>由于全局钩子函数必须包含在动态链接库中，所以本例由两个程序体来实现。 <br>1．建立钩子Mousehook.DLL <br>　　 (1)选择MFC AppWizard(DLL)创建项目Mousehook； <br>　　 (2)选择MFC Extension DLL（共享MFC拷贝）类型； <br>　　 (3)由于VC5没有现成的钩子类，所以要在项目目录中创建Mousehook.h文件，在其中建立钩子类： <br>　　 class AFX_EXT_CLASS Cmousehook:public CObject <br>　　 { <br>　　 public: <br>　　 Cmousehook(); <br>　　 //钩子类的构造函数 <br>　　 ~Cmousehook(); <br>　　 //钩子类的析构函数 <br>　　 BOOL starthook(HWND hWnd); <br>　　 //安装钩子函数 <br>　　 BOOL stophook(); <br>　　 卸载钩子函数 <br>　　 }; <br>　　 (4)在Mousehook.app文件的顶部加入#include"Mousehook.h"语句； <br>　　 (5)加入全局共享数据变量： <br>　　 #pragma data_seg("mydata") <br>　　 HWND glhPrevTarWnd=NULL; <br>　　 //上次鼠标所指的窗口句柄 <br>　　 HWND glhDisplayWnd=NULL; <br>　　 //显示目标窗口标题编辑框的句柄 <br>　　 HHOOK glhHook=NULL; <br>　　 //安装的鼠标钩子句柄 <br>　　 HINSTANCE glhInstance=NULL; <br>　　 //DLL实例句柄 <br>　　 #pragma data_seg() <br>　　 (6)在DEF文件中定义段属性： <br>　　 SECTIONS <br>　　 mydata READ WRITE SHARED <br>　　 (7)在主文件Mousehook.cpp的DllMain函数中加入保存DLL实例句柄的语句： <br>　　 DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) <br>　　 { <br>　　 //如果使用lpReserved参数则删除下面这行 <br>　　 UNREFERENCED_PARAMETER(lpReserved); <br>　　 if (dwReason == DLL_PROCESS_ATTACH) <br>　　 { <br>　　 TRACE0("MOUSEHOOK.DLL Initializing!\n"); <br>　　 //扩展DLL仅初始化一次 <br>　　 if (!AfxInitExtensionModule(MousehookDLL, hInstance)) <br>　　 return 0; <br>　　 new CDynLinkLibrary(MousehookDLL); <br>　　 //把DLL加入动态MFC类库中 <br>　　 glhInstance=hInstance; <br>　　 //插入保存DLL实例句柄 <br>　　 } <br>　　 else if (dwReason == DLL_PROCESS_DETACH) <br>　　 { <br>　　 TRACE0("MOUSEHOOK.DLL Terminating!\n"); <br>　　 //终止这个链接库前调用它 <br>　　 AfxTermExtensionModule(MousehookDLL); <br>　　 } <br>　　 return 1; <br>　　 } <br>　　 (8)类Cmousehook的成员函数的具体实现： <br>　　 Cmousehook::Cmousehook() <br>　　 //类构造函数 <br>　　 { <br>　　 } <br>　　 Cmousehook::~Cmousehook() <br>　　 //类析构函数 <br>　　 { <br>　　 stophook(); <br>　　 } <br>　　 BOOL Cmousehook::starthook(HWND hWnd) <br>　　 //安装钩子并设定接收显示窗口句柄 <br>　　 { <br>　　 BOOL bResult=FALSE; <br>　　 glhHook=SetWindowsHookEx(WH_MOUSE,MouseProc,glhInstance,0); <br>　　 if(glhHook!=NULL) <br>　　 bResult=TRUE; <br>　　 glhDisplayWnd=hWnd; <br>　　 //设置显示目标窗口标题编辑框的句柄 <br>　　 return bResult; <br>　　 } <br>　　 BOOL Cmousehook::stophook() <br>　　 //卸载钩子 <br>　　 { <br>　　 BOOL bResult=FALSE; <br>　　 if(glhHook) <br>　　 { <br>　　 bResult= UnhookWindowsHookEx(glhHook); <br>　　 if(bResult) <br>　　 { <br>　　 glhPrevTarWnd=NULL; <br>　　 glhDisplayWnd=NULL;//清变量 <br>　　 glhHook=NULL; <br>　　 } <br>　　 } <br>　　 return bResult; <br>　　 } <br>　　 (9)钩子函数的实现： <br>　　 LRESULT WINAPI MouseProc(int nCode,WPARAM wparam,LPARAM lparam) <br>　　 { <br>　　 LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *) lparam; <br>　　 if (nCode&gt;=0) <br>　　 { <br>　　 HWND glhTargetWnd=pMouseHook-&gt;hwnd; <br>　　 //取目标窗口句柄 <br>　　 HWND ParentWnd=glhTargetWnd; <br>　　 while (ParentWnd !=NULL) <br>　　 { <br>　　 glhTargetWnd=ParentWnd; <br>　　 ParentWnd=GetParent(glhTargetWnd); <br>　　 //取应用程序主窗口句柄 <br>　　 } <br>　　 if(glhTargetWnd!=glhPrevTarWnd) <br>　　 { <br>　　 char szCaption[100]; <br>　　 GetWindowText(glhTargetWnd,szCaption,100); <br>　　 //取目标窗口标题 <br>　　 if(IsWindow(glhDisplayWnd)) <br>　　 SendMessage(glhDisplayWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)szCaption); <br>　　 glhPrevTarWnd=glhTargetWnd; <br>　　 //保存目标窗口 <br>　　 } <br>　　 } <br>　　 return CallNextHookEx(glhHook,nCode,wparam,lparam); <br>　　 //继续传递消息 <br>　　 } <br>　　 (10)编译项目生成mousehook.dll。 </p>
<p>2．创建钩子可执行程序 <br>　　 (1)用MFC的AppWizard(EXE)创建项目Mouse； <br>　　 (2)选择&#8220;基于对话应用&#8221;并按下&#8220;完成&#8221;键； <br>　　 (3)编辑对话框，删除其中原有的两个按钮，加入静态文本框和编辑框，用鼠标右键点击静态文本框，在弹出的菜单中选择&#8220;属性&#8221;，设置其标题为&#8220;鼠标所在的窗口标题&#8221;； </p>
　　 (4)在Mouse.h中加入对Mousehook.h的包含语句#Include"..\Mousehook\Mousehook.h"； <br>　　 (5)在CMouseDlg.h的CMouseDlg类定义中添加私有数据成员： <br>　　 CMouseHook m_hook;//加入钩子类作为数据成员 <br>　　 (6)修改CmouseDlg::OnInitDialog()函数： <br>　　 BOOL CMouseDlg::OnInitDialog() <br>　　 { <br>CDialog::OnInitDialog(); <br>　　 ASSERT((IDM_ABOUTBOX &amp; 0xFFF0) == IDM_ABOUTBOX); <br>　　 ASSERT(IDM_ABOUTBOX &lt;0xF000); <br>　　 CMenu* pSysMenu = GetSystemMenu(FALSE); <br>　　 if (pSysMenu != NULL) <br>　　 { <br>　　 CString strAboutMenu; <br>　　 strAboutMenu.LoadString(IDS_ABOUTBOX); <br>　　 if (!strAboutMenu.IsEmpty()) <br>　　 { <br>　　 pSysMenu-&gt;AppendMenu(MF_SEPARATOR); <br>　　 pSysMenu-&gt;AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); <br>　　 } <br>　　 } <br>　　 SetIcon(m_hIcon, TRUE);//Set big icon <br>　　 SetIcon(m_hIcon, FALSE);//Set small icon <br>　　 //TODO: Add extra initialization here <br>　　 CWnd * pwnd=GetDlgItem(IDC_EDIT1); <br>　　 //取得编辑框的类指针 <br>　　 m_hook.starthook(pwnd-&gt;GetSafeHwnd()); <br>　　 //取得编辑框的窗口句柄并安装钩子 <br>　　 return TRUE; <br>　　 //return TRUE unless you set the focus to a control <br>　　 } <br>　　 (7)链接DLL库，即把..\Mousehook\debug\Mousehook.lib加入到项目设置链接标签中； <br>　　 (8)编译项目生成可执行文件； <br>　　 (9)把Mousehook.DLL拷贝到..\mouse\debug目录中； <br>　　 (10)先运行几个可执行程序，然后运行Mouse.exe程序，把鼠标在不同窗口中移动，在Mouse.exe程序窗口中的编辑框内将显示出鼠标所在的应用程序主窗口的标题。<br>
<img src ="http://www.cppblog.com/iniwf/aggbug/112529.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iniwf/" target="_blank">iniwf</a> 2010-04-14 10:11 <a href="http://www.cppblog.com/iniwf/archive/2010/04/14/112529.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hook导入表 —— 实现挂钩FreeLibaray和HOOK延迟加载模块的API</title><link>http://www.cppblog.com/iniwf/archive/2009/08/30/94827.html</link><dc:creator>iniwf</dc:creator><author>iniwf</author><pubDate>Sun, 30 Aug 2009 13:57:00 GMT</pubDate><guid>http://www.cppblog.com/iniwf/archive/2009/08/30/94827.html</guid><wfw:comment>http://www.cppblog.com/iniwf/comments/94827.html</wfw:comment><comments>http://www.cppblog.com/iniwf/archive/2009/08/30/94827.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iniwf/comments/commentRss/94827.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iniwf/services/trackbacks/94827.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Hook导入表&nbsp;——&nbsp;实现挂钩FreeLibaray和HOOK延迟加载模块的API&nbsp;　　最近在研究Windows&nbsp;Ring3上的API&nbsp;Hook，对HOOK导入表这种方法进行了研究。HOOK导入表所用的C++类大同小异，不同的就是如何实现HOOK一个延迟加载的模块中的函数，以及FreeLibaray某个函数之后再次LoadLibaray加载这个模块...&nbsp;&nbsp;<a href='http://www.cppblog.com/iniwf/archive/2009/08/30/94827.html'>阅读全文</a><img src ="http://www.cppblog.com/iniwf/aggbug/94827.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iniwf/" target="_blank">iniwf</a> 2009-08-30 21:57 <a href="http://www.cppblog.com/iniwf/archive/2009/08/30/94827.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>API hooking revealed</title><link>http://www.cppblog.com/iniwf/archive/2009/04/11/79648.html</link><dc:creator>iniwf</dc:creator><author>iniwf</author><pubDate>Sat, 11 Apr 2009 15:54:00 GMT</pubDate><guid>http://www.cppblog.com/iniwf/archive/2009/04/11/79648.html</guid><wfw:comment>http://www.cppblog.com/iniwf/comments/79648.html</wfw:comment><comments>http://www.cppblog.com/iniwf/archive/2009/04/11/79648.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iniwf/comments/commentRss/79648.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iniwf/services/trackbacks/79648.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转自http://www.codeproject.com/KB/system/hooksys.aspx    Download source files - 69 Kb    Download demo project - 139 Kb Introduction Intercepting Win32 API calls has always been a chall...&nbsp;&nbsp;<a href='http://www.cppblog.com/iniwf/archive/2009/04/11/79648.html'>阅读全文</a><img src ="http://www.cppblog.com/iniwf/aggbug/79648.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iniwf/" target="_blank">iniwf</a> 2009-04-11 23:54 <a href="http://www.cppblog.com/iniwf/archive/2009/04/11/79648.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>