可以用GetAsyncKeyState Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer用Timer判断 If GetAsyncKeyState(vbKeyTab) Then Me.Caption = "Down" Else Me.Caption = "Up" End If
可是用TIMER好象会占用很多资源的哦,能不能有按键时才触发?这样比较合理点.
' 应该这样写。Private Sub Form_Load() Me.KeyPreview = True End SubPrivate Sub Form_KeyPress(KeyAscii As Integer) If KeyAscii = Asc(vbTab) Then MsgBox "ok" End If End Sub
不行呀,Form_KeyPress事件在按TAB时根本没有反应!keydown也是....
'用键盘HOOK试一下吧.'模块块代码 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 Declare Function UnhookWindowsHookEx Lib "user32" _ (ByVal hHook As Long) As Long Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _ ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As LongPublic hnexthookproc As Long Public Const HC_ACTION = 0 Public Const WH_KEYBOARD = 2Public Sub UnHookKBD() If hnexthookproc <> 0 Then UnhookWindowsHookEx hnexthookproc hnexthookproc = 0 End If End Sub Public Function EnableKBDHook() If hnexthookproc <> 0 Then Exit Function End If hnexthookproc = SetWindowsHookEx(WH_KEYBOARD, AddressOf _ MyKBHFunc, App.hInstance, 0) If hnexthookproc <> 0 Then EnableKBDHook = hnexthookproc End If End Function Public Function MyKBHFunc(ByVal iCode As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long MyKBHFunc = 0 '讯息要处理 If iCode < 0 Then MyKBHFunc = CallNextHookEx(hnexthookproc, iCode, wParam, lParam) Exit Function End If If iCode = 3 And wParam > 0 And lParam < 0 Then Debug.Print "按了TAB键" End If Call CallNextHookEx(hnexthookproc, iCode, wParam, lParam) End Function'窗体代码Private Sub Form_Load() Call EnableKBDHook End SubPrivate Sub Form_Unload(Cancel As Integer) Call UnHookKBD End Sub
下面是一个捕捉Tab键的例子。由于Tab键可以触发LostFocus事件,在这个例子中使用GetKeyState函数检查是否是使用Tab键触发的事件。 Private Declare Function GetKeyState Lib "User32" (ByVal nVirtKey As Long) As Integer ' Virtual key values Const VK_TAB = &H9 Const VK_SHIFT = &H10
Sub txtAreaCode_LostFocus() Dim iRetVal As Integer
' Check for a tab out of this control ' Skip the state field iRetVal = GetKeyState(VK_SHIFT) ' 如果没有按shift,检查tab If iRetVal <> -128 And iRetVal <> -127 Then iRetVal = GetKeyState(VK_TAB) If iRetVal = -128 Or iRetVal = -127 Then ' tab键按下 txtPhone.SetFocus End If End If End Sub
// 不行呀,Form_KeyPress事件在按TAB时根本没有反应!keydown也是....' 要在窗体加载后先将它的 KeyPreview 属性设为 True,我已经 ' 在 Windows Server 2003 下测试过了没问题, Private Sub Form_Load() Me.KeyPreview = True End SubPrivate Sub Form_KeyPress(KeyAscii As Integer) If KeyAscii = Asc(vbTab) Then MsgBox "ok" End If End Sub
// Sun_Jianhua(铁拳) 的可以实现. 但键盘上的方向键不能
// openforever(++) 方向键就在 Form_KeyDown 事件中捕获嘛,呵呵。
TO: Sun_Jianhua(铁拳) 就是奇怪,为什么在WINDOWS 2000和VB6+SP5,就不能用你的方法?会不会是我的系统有问题,或者是我的VB有问题??
' 给你写了段键盘钩子的代码,测试了一下没问题,这个在 Win2000 下应该不会出问题的。' 把这段代码放在窗体中 Option ExplicitPrivate 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 Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As LongPrivate Const WH_KEYBOARD = 2Private Sub Form_Load() hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, App.hInstance, 0) End SubPrivate Sub Form_Unload(Cancel As Integer) If hHook <> 0 Then UnhookWindowsHookEx hHook End If End Sub' 把这段代码放在标准模块中 Option ExplicitPrivate Const HC_ACTION = 0 Private Const HC_NOREMOVE = 3Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As LongPublic hHook As LongPublic Function KeyboardProc(ByVal code As Long, ByVal wParam As Long, ByVal lParam As Long) As Long If code = HC_NOREMOVE And wParam = Asc(vbTab) Then Debug.Print "Tab 键被按下!", code, lParam End If KeyboardProc = CallNextHookEx(hHook, code, wParam, lParam) End Function
Me.Caption = "Down"
Else
Me.Caption = "Up"
End If
Me.KeyPreview = True
End SubPrivate Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = Asc(vbTab) Then
MsgBox "ok"
End If
End Sub
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
Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As LongPublic hnexthookproc As Long
Public Const HC_ACTION = 0
Public Const WH_KEYBOARD = 2Public Sub UnHookKBD()
If hnexthookproc <> 0 Then
UnhookWindowsHookEx hnexthookproc
hnexthookproc = 0
End If
End Sub
Public Function EnableKBDHook()
If hnexthookproc <> 0 Then
Exit Function
End If
hnexthookproc = SetWindowsHookEx(WH_KEYBOARD, AddressOf _
MyKBHFunc, App.hInstance, 0)
If hnexthookproc <> 0 Then
EnableKBDHook = hnexthookproc
End If
End Function
Public Function MyKBHFunc(ByVal iCode As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long MyKBHFunc = 0 '讯息要处理
If iCode < 0 Then
MyKBHFunc = CallNextHookEx(hnexthookproc, iCode, wParam, lParam)
Exit Function
End If
If iCode = 3 And wParam > 0 And lParam < 0 Then
Debug.Print "按了TAB键"
End If
Call CallNextHookEx(hnexthookproc, iCode, wParam, lParam)
End Function'窗体代码Private Sub Form_Load()
Call EnableKBDHook
End SubPrivate Sub Form_Unload(Cancel As Integer)
Call UnHookKBD
End Sub
Private Declare Function GetKeyState Lib "User32" (ByVal nVirtKey As Long) As Integer
' Virtual key values
Const VK_TAB = &H9
Const VK_SHIFT = &H10
Sub txtAreaCode_LostFocus()
Dim iRetVal As Integer
' Check for a tab out of this control
' Skip the state field
iRetVal = GetKeyState(VK_SHIFT)
' 如果没有按shift,检查tab
If iRetVal <> -128 And iRetVal <> -127 Then
iRetVal = GetKeyState(VK_TAB)
If iRetVal = -128 Or iRetVal = -127 Then ' tab键按下
txtPhone.SetFocus
End If
End If
End Sub
' 在 Windows Server 2003 下测试过了没问题,
Private Sub Form_Load()
Me.KeyPreview = True
End SubPrivate Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = Asc(vbTab) Then
MsgBox "ok"
End If
End Sub
的可以实现.
但键盘上的方向键不能
方向键就在 Form_KeyDown 事件中捕获嘛,呵呵。
Option ExplicitPrivate 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
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As LongPrivate Const WH_KEYBOARD = 2Private Sub Form_Load()
hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, App.hInstance, 0)
End SubPrivate Sub Form_Unload(Cancel As Integer)
If hHook <> 0 Then
UnhookWindowsHookEx hHook
End If
End Sub' 把这段代码放在标准模块中
Option ExplicitPrivate Const HC_ACTION = 0
Private Const HC_NOREMOVE = 3Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As LongPublic hHook As LongPublic Function KeyboardProc(ByVal code As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If code = HC_NOREMOVE And wParam = Asc(vbTab) Then
Debug.Print "Tab 键被按下!", code, lParam
End If
KeyboardProc = CallNextHookEx(hHook, code, wParam, lParam)
End Function
原来窗体在没有文本控件时,你的第一段代码就运行正常.而用你的第二段代码很好,解决了问题!