VB利用键盘勾子实现按键消息截获
提醒:本页面将不再更新、维护或者支持,文章、评论所叙述内容存在时效性,涉及技术细节或者软件使用方面不保证能够完全有效可操作,请谨慎参考!
好久不用VB写程序了,但是不得不承认VB的简单和高开发效率,这点比C/C++要好很多,尤其是一些开发周期短,实用性较强的软件。近期应单位要求,开发个××系统(名称保密),然后有个功能就是截获按键,实现特殊的按键热键的功能,首先想到的就是SetWindowsHookEx、CallNextHookEx 和UnhookWindowsHookEx,是的,想法很好,但是在实际运用时发现这几个C/C++下好用的函数老是容易导致VB崩溃,有时连IDE一起挂了,纠结了,因为这个系统最大的要求就是稳定,不能中途崩溃,为此我还特地建立了崩溃恢复机制,好了废话不说,这个问题总是要解决的,网上找到的一类代码比较混杂,大多是有问题的,最终我在vbaccelerator找到了个稳定可行的版本,那就是 《Win32 Hooks in VB - The vbAccelerator Hook Library》 这篇文章所介绍的Hook Library [下载地址] [源代码] 。
使用方法很简单,下载那个ActiveX DLL,然后VB引用,然后在窗体级代码中输入:
Implements IWindowsHook
Private Sub Form_Load()
InstallHook Me, WH_JOURNALRECORD
End Sub
Private Sub Form_QueryUnload( _
Cancel As Integer, UnloadMode As Integer)
RemoveHook Me, WH_JOURNALRECORD
End Sub
Private Function IWindowsHook_HookProc( _
ByVal eType As vbalWinHook.EHTHookTypeConstants, _
ByVal nCode As Long, _
ByVal wParam As Long, _
ByVal lParam As Long, _
bConsume As Boolean) As Long
If (eType = WH_JOURNALRECORD) Then
Dim cEvent As cJournallParam
Set cEvent = JournalRecordlParam(lParam)
' cEvent now contains information about
' the Journal record message.
End If
End Function
当然 《Using a Journal Record Hook to Capture Mouse and Key Events from any System Window》 给出了一个完整的示例,大家不妨参考一下。
后来发现一个问题,那就是Visual Basic的ListView控件老是接收到我们要处理的按键,原本是想要处理的按键被按键勾子截获后就被“吃掉”不再继续传递,但是即使将IWindowsHook_HookProc的bConsume设为True也无济于事,后来我想起了以前看到的一个简单的办法,那就是KeyPress,看下面的代码:
Private Sub ListView1_KeyPress(KeyAscii As Integer)
' 如果按下字母B,则“吃掉”这个按键
If KeyAscii = vbKeyB Then KeyAscii = 0
End Sub
上述代码中,如果接收到字母则将KeyAscii置0,这样控件本身就不再处理这个按键了。