VB中哪些命令调用钩子函数

VB中哪些命令调用钩子函数,第1张

VB编程中钩子的实现及应用

前言

Windows系统中钩子具有相当强大的功能,通过这种技术可以对几乎所有的Windows 系统中的消息进行拦截、监视、处理。这种技术可以广泛应用于各种软件,尤其是需要有监控、自动记录等对系统进行监测功能的软件。本文针对这个专题进行了探讨,希望可以为读者朋友们起到抛砖引玉的作用。

一、钩子的机制及类型

Windows的应用程序都是基于消息驱动的,应用程序的 *** 作都依赖于它所得到的消息的类型及内容。钩子与Dos中断截获处理机制有类似之处。钩子(Hook)是Windows消息处理机制的一个平台,通过安装各种钩子,应用程序可以在上面设置子程序以监视指定窗口的某种消息,并且当消息到达目标窗口之前处理它。

在Windows中,钩子有两种,一种是系统钩子(RemoteHook),它对消息的监视是整个系统范围,另一种是线程钩子(LocalHook),它的拦截范围只有进程内部的消息。对于系统钩子,其钩子函数(HookFunction)应在Windows系统的动态链接库(DLL)中实现,而对于线程钩子来说,钩子函数可以在DLL之中实现,也可以在相应的应用程序之中实现。这是因为当开发人员创建一个钩子时,Windows先在系统内存中创建一个数据结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去,并且新的钩子将排在老的钩子的前面。当一个事件发生时,如果安装的是一个局部钩子,当前进程中的钩子函数将被调用。如果是一个远程钩子,系统就必须把钩子函数插入到其它进程的地址空间,要做到这一点就要求钩子函数必须在一个动态链接库中,所以如果想要使用远程钩子,就必须把该钩子函数放到动态链接库中去。对于钩子所监视的消息类型来说,Windws一共提供了如下几种类型:如表1所示:

表一、Windows消息类型

消息类型常量标识

消息类型

适用范围

WH_CALLWNDPROC

4

发给窗口的消息

线程或系统

WH_CALLWNDPROCRET

12

窗口返回的消息

线程或系统

WH_CBT

5

窗口变化、焦点设定等消息

线程或系统

WH_DEBUG

9

是否执行其它Hook的Hook

线程或系统

WH_FOREGROUNDIDLE

11

前台程序空闲

线程或系统

WH_GETMESSAGE

3

投放至消息队列中的消息

线程或系统

WH_JOURNALPLAYBACK

1

将所记载的消息进行回放

系统

WH_JOURNALRECORD

0

监视并记录输入消息

系统

WH_KEYBOARD

2

键盘消息

线程或系统

WH_MOUSE

7

鼠标消息

线程或系统

WH_MSGFILTER

-1

菜单滚动条、对话框消息

线程或系统

WH_SHELL

10

外壳程序的消息

线程或系统

WH_SYSMSGFILTER

6

所有线程的菜单滚动条、对话框消息

系统

二、VB编程中钩子的实现

(一)钩子函数(HOOK Function)的格式。Hook Function实际上是一个函数,如果是系统钩子,该函数必须放在动态链接库中。该函数有一定的参数格式,在VB中如下:

Private Function HookFunc(ByVal nCode As Long,ByVal wParam As Long,ByVal lParam As Long)As Long

其中,nCode代表是什么情况之下所产生的钩子,随钩子的不同而有不同组的可能值;参数wParam,lParam传回值包括了所监视到的消息内容,它随Hook所监视消息的种类和nCode的值不同而不同。对于用VB所设置的钩子函数,一般的框架形式如下:

Private Function HookFunc(ByVal nCode As Long,ByVal wParam As Long,ByVal lParam As Long)As Long

Select case of nCode

case ncode<0:hookfunc=callnexthookex(hHookFunc,nCode,wParam,lParam)

case值1:处理过程1:HookFunc=X1

case2:处理过程2:HookFunc=X1

……

end select

end Function

函数的传回值,如果消息要被处理,则传0,否则传1,吃掉消息。

(二)钩子的安装及执行。钩子的安装要用到几个API函数:可以使用API函数SetWindowsHookEx()把一个应用程序定义的钩子子程安装到钩子链表中。SetWindowsHookEx()函数的声明如下:

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

idHook值为它处理的消息类型;lpfn值为钩子子程序的地址指针。如果dwThreadId参数为0或是一个由别的进程创建的线程的标识,lpfn必须指向DLL中的钩子子程。除此以外,lpfn可以指向当前进程的一段钩子子程代码。hMod值为应用程序的句柄,标识包含lpfn所指的子程的DLL。如果dwThreadId标识当前进程创建的一个线程,而且子程代码位于当前进程,hMod必须为0。dwThreadId值为与安装的钩子子程相关联的线程的标识符,如果为0,钩子子程与所有的线程关联。钩子安装成功则返回钩子子程的句柄,失败返回0。

另外,一般应在钩子子程中调用CallNextHookEx()函数以执行钩子链表所指的下一个钩子子程,否则安装了别的钩子的应用程序就会收不到钩子通知,从而产生错误的结果。CallNextHookEx()函数的声明如下:

Declare Function CallNextHookEx Lib"user32" Alias "CallNextHookEx"(ByVal hHook As Long,ByVal ncode As Lonog, ByVal wParam As Long,lParam As Any)As Long

hHook值是SetWindowsHookEx()的传回值,nCode、wParam、lParam则是Hook函数中的三个参数。在程序终止之前,必须调用UnhookWindowsHookEx()函数释放与钩子关联的系统资源。UnhookWindowsEx()函数声明如下:

Declare Function Unhook WindowsHookEx Lib "user32" Alias "Unhook WindowsHookEx(ByVal hHook As Long)As Long

hHook为安装钩子时的返回值,即钩子子程的句柄。

(三)VB中钩子安装应注意的问题。lpfn参数是一个HookFunc的地址,VB规定必须将HookFunc代码放到标准的.BAS模块中,并以"Address Of HookFunc"传入,而不可以将其放到类模块中,也不能将其附加到窗体上。而对于RemoteHook来说,HookFunc应包含在动态链接库中,因此如果在VB中使用RemoteHook,则还要用到GetModuleHandle()、GetProcAddress()两个API函数,它们的声明如下:

Declare Function GetModuleHandle Lib"kernel32" Alias "GetModuleHandleA"(ByVal lpModuleName As String)As Long

Declare Function GetProcAddress Lib "kernel32" Alias "GetProcAddress"(ByVal hModule As Long,ByVal lpProcName As String)As Long

hmod值是含钩子过程的模块名柄,如果是LocalHook,该值可以是Null(VB中传0),而如果是RemoteHook,则可以使用GetModuleHandle("名称.dll")来传入。

三、实例--键盘消息的拦截

在程序开发时常用的有对输入消息进行监视的键盘钩子,对于所监视到的消息应进行处理,下面对键盘钩子参数的具体内容组成进行说明:

如果有键盘消息(WM_KEYUP或WM_KEYDOWN)将被处理时,则系统调用键盘钩子。

nCode为HC_ACTION或HC_NOREMOVE,若小于0,则要求处理函数向下传递该消息。

wParam表示按键键码常数,A键到Z键与其ASCII码的相应值''A''到''Z''是一致的,例如按C键,则wParam值为67。

lParam与WM_KEYDOWN同,占四个字节,其包括的内容较多,其二进制结构如下:

0

1

……

15

16

………

23

24

25

……

28

29

30

31

0-15位(Key repeat count),键码重复次数。16-23位(Scan code),按键的扫描码。24位(Extended_Key flag),扩展键(功能键、数字小键盘上的键)标志,为1则是扩展键,否则为0。25-28位被保留。29位(Context Code),状态描述码,ALT键被按下则为1,否则为0。30位(Previouskey_stateflag)指定先前的键状态,如果消息被发出之前键处于按下状态,则为1;键处于释放状态则为0。31位(Transiton_stateflag)状态转换标志,如果键是被按下值为1,如果键被放开值为0。

本例中的钩子用来监视并记录应用程序中的按键信息。在程序中,ALT+F4组合键被屏蔽。下面是部分代码:

Public hHook as Long

Private Sub Form_Load()′程序启动时安装钩子

hHook=SetWindowsHookEx(2,Address of MyKBHook,0,App.ThreadID)

End Sub

′具体的钩子程序,本例中该过程被包含在Module1中

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

If nCode>=0 then

Open "C:\Keyfile.txt" For Append As #1 ''将键盘的 *** 作记录在Keyfile.txt文件之中

''记录所 *** 作的键、 *** 作时间、日期 *** 作时的按键状态,用16进制记录

Write #1,wParam,Hex(lParam),Date,time

Close #1

MyKBHook=0 ''表示要处理这个消息

''屏蔽ALT+F4组合键

if wParam=115 And(lParam And&H20000000)<>0 Then

if(lParam And &HC000000)=0 Then ''是否进行ALT+F4 *** 作

MyHBHook=1 ''钩子吃掉这个消息

End if

End if

End if

Call CallNextHookEx(hHook,nCode,wParam,lParam)''将消息传给下一个钩子

End Function

''程序退出时卸载钩子

Private Sub Form_Unload(Cancel As Interger)

Call Unhook WindowsHookEx(hHook)

End Sub

四、总结

钩子处理程序是Windows高级编程技术,一般程序员都使用VC++等程序设计工具实现,本文表明,对于VB来说,虽然很多人认为是非专业的设计工具,但实现钩子这样的高级技术也是非常方便的。另外在使用钩子时应注意到,钩子虽然功能比较强,但如果使用不当将会严重影响系统的效率,所以要尽量避免使用系统钩子,并且在不用钩子时,应将钩子及时卸载。

使用子类化,而不是使用全局钩子。

如果非得使用全局钩子,那可以在程序最小化or失去焦点时取消Hook。

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Const GWL_WNDPROC = (-4)

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Const WM_MOUSEWHEEL = &H20A

初始化:

lHwnd=Frm.hWnd '你的窗体

sHwnd=SetWindowLong(lHwnd, GWL_WNDPROC, AddressOf MouseProc)

结束:

Call SetWindowLong(lhWnd, GWL_WNDPROC, sHwnd)

Public Function MouseProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

If Msg = WM_MOUSEWHEEL Then

Select Case wParam

Case &H780000 '向上滚

MoveUp = True

Case &HFF880000 '向下滚

MoveUp = False

End Select

EventRaised = True

End If

MouseProc = CallWindowProc(sHwnd, hWnd, Msg, wParam, lParam)

End Function


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存