mfc中钩子的使用 (来自个人博客)

阅读: 评论:0

2024年9月6日发(作者:)

mfc中钩子的使用 (来自个人博客)

钩子的安装与卸载

系统是通过调用位于钩子链表最开始处的钩子函数而进行消息拦截处理的,因此在设置

钩子时要把回调函数放置于钩子链表的链首,操作系统会使其首先被调用。由函数

SetWindowsHookEx()负责将回调函数放置于钩子链表的开始位置。SetWindowsHookEx()

函数原型声明为:

HHOOK SetWindowsHookEx(int idHook;HOOKPROC lpfn;HINSTANCE hMod;DWORD

dwThreadId);

其中,参数idHook 指定了钩子的类型,可以使用的类型有以下13种:

WH_CALLWNDPROC 系统将消息发送到指定窗口之前的“钩子”

WH_CALLWNDPROCRET 消息已经在窗口中处理的“钩子”

WH_CBT 基于计算机培训的“钩子”

WH_DEBUG 差错“钩子”

WH_FOREGROUNDIDLE 前台空闲窗口“钩子”

WH_GETMESSAGE 接收消息投递的“钩子”

WH_JOURNALPLAYBACK 回放以前通过WH_JOURNALRECORD“钩子”记录的输入消息

WH_JOURNALRECORD 输入消息记录“钩子”

WH_KEYBOARD 键盘消息“钩子”

WH_MOUSE 鼠标消息“钩子”

WH_MSGFILTER 对话框、消息框、菜单或滚动条输入消息“钩子”

WH_SHELL 外壳“钩子”

WH_SYSMSGFILTER 系统消息“钩子”

参数lpfn为指向钩子函数的指针,也即回调函数的首地址;参数hMod标识了钩子处

理函数所处模块的句柄;参数dwThreadId 指定被监视的线程,如果明确指定了某个线程的

ID就只监视该线程,此时的钩子即为线程钩子;如果该参数被设置为0,则表示此钩子为

监视系统所有线程的全局钩子。此函数在执行完后将返回一个钩子句柄。

在SetWindowsHookEx()函数完成对钩子的安装后,如果被监视的事件发生,系统会立

即调用位于相应钩子链表开始处的钩子函数进行处理,每一个钩子函数在进行处理时都要考

虑是否需要把事件传递给下一个钩子处理函数。如果需要传递,就要调用函数

CallNestHookEx()。尽管在理论上不调用CallNestHookEx()也并不算错,但在实际使

用时还是强烈建议无论是否需要进行事件传递都要在过程的最后调用一次

CallNextHookEx( ),否则将会引起一些无法预知的系统行为或是系统锁定。该函数将返回

位于钩子链表中的下一个钩子处理过程的地址,至于具体的返回值类型则要视所设置的钩子

类型而定。CallNextHookEx( )的函数原型为:

LRESULT CallNextHookEx(HHOOK hhk;int nCode;WPARAM wParam;LPARAM lParam);

其中,参数hhk为由SetWindowsHookEx()函数返回的当前钩子句柄;参数nCode为

传给钩子过程的事件代码;参数wParam和lParam 则为传给钩子处理函数的参数值,其

具体含义同设置的钩子类型有关。

由于安装钩子对系统的性能有一定的影响,所以在钩子使用完毕后应及时将其卸载以释

放其所占资源。释放钩子的函数为UnhookWindowsHookEx(),该函数比较简单只有一个参

数用于指定此前由SetWindowsHookEx()函数所返回的钩子句柄,原型声明如下:

BOOL UnhookWindowsHookEx(HHOOK hhk);

使用鼠标钩子

由于系统全局钩子在功能上完全覆盖了线程局部钩子,因此其实际使用范围要远比线程

局部钩子广泛的多。本节也由此着重对系统全局钩子的使用进行介绍。

鼠标钩子是钩子中比较常用也是使用比较简单的一类钩子。下面给出的应用示例将通过

安装鼠标全局钩子来捕获鼠标当前所处窗口的窗口标题。由于本例程使用了全局钩子,因此

首先构造全局钩子的载体——动态链接库。考虑到 Win32 DLL与Win16 DLL存在的差别,

在Win32环境下要在多个进程间共享数据,就必须采取一些措施将待共享的数据提取到一

个独立的数据段,并通过def文件将其属性设置为读写共享:

#pragma data_seg("mydata")

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

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

HWND glhHook = NULL; // 安装的鼠标钩子句柄

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

#pragma data_seg()

……

SECTIONS // def文件中将数据段TestData设置为读写共享

TestData READ WRITE SHARED

在完成上述准备工作后,在动态库输出函数StartHook()中调用SetWindowsHookEx

()函数完成对全局鼠标钩子的安装,设定鼠标钩子函数为MouseProc(),安装函数返

回的钩子句柄保存于变量glhHook中:

BOOL CMouseHook::StartHook(HWND hWnd)

{

BOOL result = FALSE;

// 安装钩子

glhHook = (HWND)SetWindowsHookEx(WH_MOUSE, MouseProc, glhInstance, 0);

if (glhHook != NULL)

result = TRUE;

glhDisplayWnd = hWnd; // 设置显示目标窗口标题编辑框的句柄

return result;

}

在鼠标钩子安装完毕后,系统内的任何鼠标动作所发出的鼠标消息均要经过钩子函数

MouseProc()的拦截过滤处理。在此进行的处理是通过获取当前鼠标所在位置下的窗口

句柄,并以此进一步得到窗口标题。在处理完成后,调用CallNextHookEx()函数将本事

件传递到钩子链表中的下一个钩子函数:

LRESULT WINAPI MouseProc(int nCode, WPARAM wParam, LPARAM lParam)

{

LPMOUSEHOOKSTRUCT pMouseHook = (MOUSEHOOKSTRUCT FAR *) lParam;

if (nCode >= 0) {

HWND glhTargetWnd = pMouseHook->hwnd; // 取目标窗口句柄

HWND ParentWnd = glhTargetWnd;

while (ParentWnd != NULL){

glhTargetWnd = ParentWnd;

ParentWnd = GetParent(glhTargetWnd); // 取应用程序主窗口句柄

}

if (glhTargetWnd != glhPrevTarWnd) {

char szCaption[100];

GetWindowText(glhTargetWnd, szCaption, 100); // 取目标窗口标题

if (IsWindow(glhDisplayWnd))

SendMessage(glhDisplayWnd, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)szCaption);

glhPrevTarWnd = glhTargetWnd; // 保存目标窗口

}

}

// 继续传递消息

return CallNextHookEx((HHOOK)glhHook, nCode, wParam, lParam);

}

此动态链接库还提供有输出函数StopHook(),调用程序通过对此函数的调用完成对

先前加载钩子的卸载。在此输出函数内则是通过UnhookWindowsHookEx()函数来卸载

指定钩子的:

BOOL CMouseHook::StopHook()

{

BOOL result = FALSE;

if (glhHook){

result = UnhookWindowsHookEx((HHOOK)glhHook); // 卸载钩子

if (result)

glhDisplayWnd = glhPrevTarWnd = glhHook = NULL;

}

return result;

}

通过编译、链接可以得到有关鼠标全局钩子的动态链接库,在经过调用程序对其的调用

后,可以实现对在当前系统所有线程中的鼠标消息的拦截处理。在钩子动态链接库加载到进

程后,只需调用输出函数StartHook()安装好全局钩子即可对鼠标消息进行拦截过滤,在

调用程序退出前调用输出函数StopHook()卸载钩子。

mfc中钩子的使用 (来自个人博客)

本文发布于:2024-09-06 21:09:40,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/1725628180362985.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:钩子   函数   鼠标   消息   全局   系统
留言与评论(共有 0 条评论)
   
验证码:
排行榜

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23