可能大家说这个VB实现不了,那你跟我做,看看能不能实现.其实实现起来还是满简单的.........只是拦截是做不得的了..代码只写了核心部分,其他的判断转化等以注释的方式体现出来了,用到的朋友自己改改..
窗体上,画2个LABEL控件,把LABEL2名字改为labKeyState即可(代码中只是利用了这个家伙的事件来触发一些操作)
窗体代码如下:
Private Sub Form_Activate()
labKeyState.Caption = ""
End Sub
Private Sub Form_Load()
'开始
SetTimer Me.hwnd, 0, 1, AddressOf TimerProc
End Sub
Private Sub Form_Unload(Cancel As Integer)
'停止
KillTimer Me.hwnd, 0
End Sub
Private Sub labKeyState_Change()
Dim sTmp As String
sTmp = labKeyState.Caption '可以在这里获取扫描码对应的键值
If sTmp <> "" Then
'这里,执行你要的操作,我执行了显示按键虚拟码
Label1.Caption = sTmp
End If
End Sub
模块代码如下:
Option Explicit
Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Declare Function GetAsyncKeyState Lib "user32" (ByVal vkey As Long) As Integer
Global Cnt As Long, Ret As Long
'获取按下的是哪个键
Function GetPressedKey(ByVal labView As Label) As Long
For Cnt = 1 To 121 '112-121 为 F1-F10
If GetAsyncKeyState(Cnt) <> 0 Then
labView.Caption = ""
GetPressedKey = Cnt
'这里加入2个判断,即可实现正确的控制..
'第一个,如果按键为1,2,4(鼠标左右中键)用鼠标双击间隔时间判断是否执行If Ret = Cnt Then Exit Function,并判断鼠标位置,所在控件句柄等等即可
'第二个,如果为其他按键则大多来自键盘,那么判断键盘按键重复间隔,如果小于执行If Ret = Cnt Then Exit Function
If Ret = Cnt Then Exit Function '如果按下的键重复,表示一次按键还没有结束,不重复进行修改
labView.Caption = Cnt
Exit For
End If
Next Cnt
End Function
Sub TimerProc(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
Ret = GetPressedKey(FrmMain!labKeyState)
End Sub
就这样了,你可以开始测试......看看是不是没有焦点时也可以获取到按键...这个代码呢,在某些游戏里"定义全局热键"的代码不好用的时候也可以用的....只要你按下了键,这个代码就能获取,除非按键被人HOOK掉了.
今天对这篇提到的功能进行了深入的分析,发现了一些问题,由于我的疏忽,可能导致使用以上代码时发生一些错误或一些不便,现在澄清一下这些问题。
1、该函数GetAsyncKeyState工作在系统级,即很难被HOOK掉,这个是我认识的模糊,导致的问题,可能影响不大。
2、以上代码进行了反复的调用,有很多冗余的部分,建议将该功能写为类,在判断Cnt <> Ret 后引发事件: RaiseEvent KeyPass(Cnt) ,在类的开头,可以做如下声明:Public Event KeyPass(ByVal KeyState As Integer),此事件返回值将为按键码。