数的形式是各不相同的。下面以鼠标钩子函数举例说明钩子函数
的原型:
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-3\MouseHook”目录下。
本节通过一个鼠标钩子实例来介绍全局钩子的应用方法。该实例的详细源代码请见附带
光盘,其中MouseHookDll 目录下的工程是全局鼠标钩子的实现动态链接库。MouseTest 工程
通过调用MouseHookDll 的动态链接库接口安装鼠标钩子并利用。在本例中鼠标钩子函数通
过判断记录当前窗口的句柄来判断鼠标是否离开窗口边界,并将鼠标位置处的窗口名称实时
地显示出来。
在MouseHookDll 中实现全局钩子,首先是全局共享数据的实现。这里利用#pragma
枫叶文学网www.fywxw.com
第10 章 动态链接库
·275·
d