学校的比赛终于结束了,辛苦了整整一个暑假终于可以抽出点时间来写博客了~~~~~
好的,那现在就把我对局部钩子的研究心得和大家共享一下吧,因为写代码的时候没有注意整理下资料,现在发现有些东西都忘记怎样写了- -!!所以有错漏的话请大家多多包涵并且欢迎指正!!
其实早在N年前网上有位高人就翻译过MSDN里面对于HOOK介绍的一篇英文文档(英文文档,wlclass翻译的中文文档),里面说的东西其实也非常之详细了的,但是他的文章只是一篇翻译文档,没有实质性的东西——源代码!呵呵。。所以我便写了这篇文字。。。。下面主要简单介绍HOOK回调过程的使用方法。。。
一般来说,HOOK的回调函数声明都是下面的形式
- Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
nCode参数一般用来说明当前是否适合处理消息,当该参数小于0时表示当前不应处理任何消息,应立即将消息传给CallNextHookEx函数并且回调函数的返回值要是这个API函数的返回值,具体用法如下:
- HookProc = CallNextHookEx(hHook, nCode, wParam, ByVal lParam)
若此参数大于0,则不同的HOOK类型可能返回不同的值以确定应该怎样处理HOOK到的消息。比如HOOK类型是WH_JOURNALRECORD,则nCode参数可能返回的值是HC_ACTION、HC_SYSMODALOFF和HC_SYSMODALON,具体使用方法请参见我的代码。
wParam参数对于不同的HOOK类型可能返回的值的意义也是不一样的,具体使用方法也请参见我的代码。
lParam参数对于大部分的HOOK来说是一个指针,我为了通用所以将它声明成Byval lParam As Long的形式,再在代码里面用CopyMemory复制到一个结构体里面,其实大家也可以用下面的形式来进行声明(假设我用的HOOK类型是WH_DEBUG):
- Function DebugProc(ByVal nCode As Long, ByVal wParam As Long, DHI As DEBUGHOOKINFO) As Long
这样演示代码里面的下面这两行就可以省略不要了:
- ...
- Dim DHI As DEBUGHOOKINFO
- ...
- CopyMemory DHI, ByVal lParam, Len(DHI)
- ...
并且代码中两次出现的这行代码
- DebugProc = CallNextHookEx(hHook, nCode, wParam, Byval lParam)
应该改成
- DebugProc = CallNextHookEx(hHook, nCode, wParam, DHI)
最后再多嘴说一下,wlclass早前提供的代码只有“输入消息记录/回放钩子”一个,他代码中回放钩子的回调函数返回值使用了50,造成了记录和回放时输入消息的时间不一致,比如有可能记录时鼠标指针是疯狂地在屏幕上游走,而回放时却发现鼠标指针以恒定的速度在移动。其实这个回调函数正确的返回值应该是两次输入消息记录的时间差,单位是毫秒,这样就应该用个全局函数先将上一个记录的时间记录下来,再在下一次回放时用当前的时间减去记录的时间方能得出正确的时间差,可能wlclass嫌代码麻烦直接用50来代替,这点我想应该向大家说明一下。
还有其他的细节问题请参考我提供的演示代码吧,这些代码是我参考了MSDN,花了一个下午的时间才做出来的。。。因为时间比较赶,难免会有些错漏,如果有哪位高手发现了欢迎提出指正!!!