VB利用键盘勾子实现按键消息截获

!本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使用方面,本人不保证相应的兼容和可操作性。

好久不用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引用,然后在窗体级代码中输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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,看下面的代码:

1
2
3
4
Private Sub ListView1_KeyPress(KeyAscii As Integer)
  ' 如果按下字母B,则“吃掉”这个按键
  If KeyAscii = vbKeyB Then KeyAscii = 0
End Sub

上述代码中,如果接收到字母则将KeyAscii置0,这样控件本身就不再处理这个按键了。

若无特别说明,本网站文章均为原创,原则上这些文章不允许转载,但是如果阁下是出于研究学习目的可以转载到阁下的个人博客或者主页,转载遵循创作共同性“署名-非商业性使用-相同方式共享”原则,请转载时注明作者出处谢绝商业性、非署名、采集站、垃圾站或者纯粹为了流量的转载。谢谢合作!
请稍后...

发表评论

电子邮件地址不会被公开。 必填项已用*标注