什么是钩子函数?钩子函数的使用。

什么是钩子函数?钩子函数的使用。,第1张

WINDOWS的钩子函数可以认为是WINDOWS的主要特性之一。利用它们,您可以捕捉您自己进程或其它进程发生的事件。通过“钩挂”,您可以给WINDOWS一个处理或过滤事件的回调函数,该函数也叫做“钩子函数”,当每次发生您感兴趣的事件时,WINDOWS都将调用该函数。一共有两种类型的钩子:局部的和远程的。

局部钩子仅钩挂您自己进程的事件。

远程的钩子还可以将钩挂其它进程发生的事件。远程的钩子又有两种:

基于线程的 它将捕获其它进程中某一特定线程的事件。简言之,就是可以用来观察其它进程中的某一特定线程将发生的事件。

系统范围的 将捕捉系统中所有进程将发生的事件消息。 当您创建一个钩子时,WINDOWS会先在内存中创建一个数据结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去。新的钩子将加到老的前面。当一个事件发生时,如果您安装的是一个局部钩子,您进程中的钩子函数将被调用。如果是一个远程钩子,系统就必须把钩子函数插入到其它进程的地址空间,要做到这一点要求钩子函数必须在一个动态链接库中,所以如果您想要使用远程钩子,就必须把该钩子函数放到动态链接库中去。当然有两个例外:工作日志钩子和工作日志回放钩子。这两个钩子的钩子函数必须在安装钩子的线程中。原因是:这两个钩子是用来监控比较底层的硬件事件的,既然是记录和回放,所有的事件就当然都是有先后次序的。所以如果把回调函数放在DLL中,输入的事件被放在几个线程中记录,所以我们无法保证得到正确的次序。故解决的办法是:把钩子函数放到单个的线程中,譬如安装钩子的线程。

钩子一共有14种,以下是它们被调用的时机:

WH_CALLWNDPROC 当调用SendMessage时

WH_CALLWNDPROCRET 当SendMessage的调用返回时

WH_GETMESSAGE 当调用GetMessage 或 PeekMessage时

WH_KEYBOARD 当调用GetMessage 或 PeekMessage 来从消息队列中查询WM_KEYUP 或 WM_KEYDOWN 消息时

WH_MOUSE 当调用GetMessage 或 PeekMessage 来从消息队列中查询鼠标事件消息时

WH_HARDWARE 当调用GetMessage 或 PeekMessage 来从消息队列种查询非鼠标、键盘消息时

WH_MSGFILTER 当对话框、菜单或滚动条要处理一个消息时。该钩子是局部的。它时为那些有自己的消息处理过程的控件对象设计的。

WH_SYSMSGFILTER 和WH_MSGFILTER一样,只不过是系统范围的

WH_JOURNALRECORD 当WINDOWS从硬件队列中获得消息时

WH_JOURNALPLAYBACK 当一个事件从系统的硬件输入队列中被请求时

WH_SHELL 当关于WINDOWS外壳事件发生时,譬如任务条需要重画它的按钮.

WH_CBT 当基于计算机的训练(CBT)事件发生时

WH_FOREGROUNDIDLE 由WINDOWS自己使用,一般的应用程序很少使用

WH_DEBUG 用来给钩子函数除错

附:如何使用钩子函数(接收到字母A按下时,窗体由最小化d出的完整的代码)

Public Declare Function CallNextHookEx Lib "user32" _

(ByVal hHook As Long, _

ByVal nCode As Long, _

ByVal wParam As Long, _

ByVal lParam As Long) As Long

Public Declare Function UnhookWindowsHookEx Lib "user32" _

(ByVal hHook As Long) As Long

Public Declare Function SetWindowsHookEx Lib "user32" _

Alias "SetWindowsHookExA" _

(ByVal idHook As Long, _

ByVal lpfn As Long, _

ByVal hmod As Long, _

ByVal dwThreadId As Long) As Long

Public Const WH_KEYBOARD = 2

Public Const KEY_WINSTART = 91

Public Const KEY_WINMENU = 93

Global hHook As Long

Public Function KeyboardProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

If nCode >= 0 Then

If wParam = KEY_WINMENU Or wParam = KEY_WINSTART Then

If (lParam And &HC0000000) = 0 Then

MsgBox "", , ""

KeyboardProc = 1

Exit Function

End If

End If

End If

KeyboardProc = CallNextHookEx(hHook, nCode, wParam, lParam)

End Function

Option Explicit

Private Sub Command1_Click()

form2.Show 1

End Sub

Private Sub form_Load()

hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, 0&, App.ThreadID)

Me.Show

End Sub

Private Sub form_Unload(Cancel As Integer)

Call UnhookWindowsHookEx(hHook)

End Sub

.版本 2

.DLL命令 api_设置系统钩子, 整数型, "user32.dll", "SetWindowsHookExA", , , SetWindowsHookEx

.参数 钩子类型, 整数型, , idHook

.参数 回调函数地址, 整数型, , lpfn

.参数 实例句柄, 整数型, , hmod

.参数 线程ID, 整数型, , dwThreadId

.DLL命令 api_呼叫下一钩子, 整数型, "user32.dll", "CallNextHookEx", , , CallNextHookEx

.参数 钩子句柄, 整数型, , hHook

.参数 回调函数参数1, 整数型, , ncode

.参数 回调函数参数2, 整数型, , wParam

.参数 回调函数参数3, 整数型, , lParam

.DLL命令 api_释放系统钩子, 整数型, "user32.dll", "UnhookWindowsHookEx", , , UnhookWindowsHookEx

.参数 钩子句柄, 整数型, , hHook

.DLL命令 api_取实例句柄, 整数型, , "GetModuleHandleA", , ,

.参数 程序名, 整数型

.DLL命令 api_拷贝内存, 整数型, "kernel32", "RtlMoveMemory", , , RtlMoveMemory

.参数 回调结构, 鼠标结构, , lpvDest

.参数 钩子回调函数参数3, 整数型, , lpvSource

.参数 尺寸, 整数型, , cbCopy

.版本 2

.数据类型 鼠标结构, 公开

.成员 成员1, 整数型

.成员 成员2, 坐标结构

.成员 成员3, 整数型

.数据类型 坐标结构

.成员 x, 整数型

.成员 y, 整数型

.版本 2

.支持库 spec

.程序集 窗口程序集1

.程序集变量 钩子句柄, 整数型

.子程序 _按钮1_被单击

钩子句柄 = api_设置系统钩子 (14, 取子程序地址 (&鼠标钩子回调函数), api_取实例句柄 (0), 0)

.子程序 鼠标钩子回调函数, 整数型

.参数 参数1

.参数 参数2

.参数 参数3

.局部变量 鼠标信息, 鼠标结构

.局部变量 坐标z, 坐标结构

.判断开始 (参数2 = 513)

_启动窗口.标题 = “你按下了鼠标左键”

.默认

.判断结束

.判断开始 (参数2 = 514)

_启动窗口.标题 = “你放开了鼠标左键”

.默认

.判断结束

.判断开始 (参数2 = 516)

_启动窗口.标题 = “你按下了鼠标右键”

.默认

.判断结束

.判断开始 (参数2 = 517)

_启动窗口.标题 = “你放开了鼠标右键”

.默认

.判断结束

.如果真 (参数2 = 512)

api_拷贝内存 (鼠标信息, 参数3, 10)

坐标z = 鼠标信息.成员2

输出调试文本 (“x=” + 到文本 (坐标z.x))

输出调试文本 (“y=” + 到文本 (坐标z.x))

.如果真结束

返回 (api_呼叫下一钩子 (钩子句柄, 参数1, 参数2, 参数3))

.子程序 _按钮2_被单击

api_释放系统钩子 (钩子句柄)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11374259.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存