-
I have a form where I have to catch every keypress, so I've put that in the Form_KeyDown(etc.) event. The thing is, the event doesn't fire if, say, a commandbutton has the focus. I don't want to write code in all of the commands, listboxes, etc KeyDown event.
How do I catch every single keypress?
I am subclassing anyway, so that wouldn't be any extra trouble.
Any help?
pleeeeeeeeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaaaaaaaaaaase?
-
Just set the KeyPreview property of the form to True.
-
I didn't know that, thanks a lot.
-
Use GetAsyncKeyState (will work for System-Wide tracking)
Code:
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Sub Timer1_Timer()
'Check if A was pressed
If GetAsyncKeyState(vbKeyA) Then MsgBox ("'A' was pressed")
End Sub
-
Thanks, Meg, but I'm only really looking for key presses if my form has the focus.
-
Is there any way to use GetAsyncKeyState to 'follow' what is being typed in other programs? I did this:
For n = 8 To 255
If GetAsyncKeyState(n) Then Text1.SelText = Chr(n)
Next
Which works to an extent, but still comes up with weird stuff for some codes, like 8 for delete etc. Also, is there any way to get lower-case characters as well as upper-case ones? Sorry if this is a bit demanding but it's something I've never come across before :)
-
Try this:
Code:
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Sub Timer1_Timer()
Dim iKey As Integer
For iKey = 3 To 255
If GetAsyncKeyState(iKey) Then Debug.Print iKey
Next
End Sub
The reason it is started at 3 is because 1 & 2 are the left and right mouse buttons, as Megatron pointed out.
-
Getforegroundwindow api should tell you which window has focus, well you could find it in win32api.txt or using apiviewer (I don't have vb on this comp);)
-
If your Subclassing, why not just use it to tell whether the form has lost focus?
Code:
Option Explicit
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal ndx As Long, ByVal newValue As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
' This is used with the SetWindowLong API function.
Const GWL_WNDPROC = -4
Public Const WM_KILLFOCUS = &H8
Dim saveHWnd As Long ' The handle of the subclassed window.
Dim oldProcAddr As Long ' The address of the original window procedure
Sub StartSubclassing(ByVal hWnd As Long)
saveHWnd = hWnd
oldProcAddr = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WndProc)
End Sub
Sub StopSubclassing()
SetWindowLong saveHWnd, GWL_WNDPROC, oldProcAddr
End Sub
Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
' Send the message to the original window procedure, and then
' return Windows the return value from the original procedure.
WndProc = CallWindowProc(oldProcAddr, hWnd, uMsg, wParam, lParam)
Select Case uMsg
Case WM_KILLFOCUS
'Form has lost focus
Form1.WindowState = 1
End Select
End Function
Private Sub Form_Load()
StartSubclassing Me.hWnd
End Sub
Private Sub Form_Unload(Cancel As Integer)
StopSubclassing
End Sub