欢迎光临

木子屋

标题: 什么是钩子函数

作者: dnawo

日期: 2009-08-29 02:58 AM

分类: Win编程

内容: 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按下时，窗体由最小化弹出的完整的代码）
复制内容到剪贴板 程序代码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

+ 查看当前日志评论 (0)

登录

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 1.039 ms

返回

标题: 什么是钩子函数

你没有权限发表评论

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 1.039 ms

返回

暂无评论

返回

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 1.068 ms

返回