Re: How to avoid that a key can be hold down



On 31 Jul, 16:01, Stefan Mueller <seekw...@xxxxxxxxx> wrote:

Today I'm doing BeastFish's solution with a flag But
it doesn't work in any case. E.g. if a Timer event
shows a MsgBox or if you open another form by clicking
a button then I don't get the KeyUp event and therefore
my program doesn't know if F12 has been relaesed or not.
PS: F12 should only work on the main form. If e.g. a
MsgBox is displayed it must not work. The problem with
the mentioned MsgBox is that I can't use the KeyUp event
to track if F12 has been released or not.

Actually this one caused me a little more grief than expected. I
thought that it would be very easy to do all this stuff in an App wide
keyboard hook, and it in fact would have been easy if you wanted to
detect and react to the pressing of the F12 key on an App wide basis,
because the entire code could have been in the hook. But your
requirement that a "key down" should be detected only on a specific
Form (your main Form) coupled with the requirement that the "key up"
should be detected App wide in order to prevent multiple actions at
the key repeat rate wherever it occurred, complicated things a little.
Either we could place all the code in the hook and find some way
inside the hook of detecting which Form or MsgBox was active or we
could use both the hook code and the Form's KeyDown event and find
some way of the hook telling the KeyDown what has happened previously
with the key up. I decided to try the latter method, and after a few
in itial teething troubles it seems to be working fine. Check it out
and see what you think. There are two blocks of code below, one for a
Module and one for your Form. For test purposes start a new VB project
using one Form and one code module and place a List Box on the Form:

Mike

' *** START OF FORM CODE ***
Option Explicit
Private Sub Form_Load()
HookKeyboard
KeyPreview = True
F12UpLast = True
Caption = "Press F12"
End Sub

Private Sub Form_Unload(Cancel As Integer)
UnHookKeyboard
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, _
Shift As Integer)
Static nCount As Long
If KeyCode = vbKeyF12 And F12UpLast = True Then
nCount = nCount + 1
List1.AddItem Format(nCount) & " " & Now
F12UpLast = False
End If
End Sub
' *** END OF FORM CODE ***
'
' *** START OF MODULE CODE ***
Option Explicit
Private 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 CallNextHookEx Lib "user32" _
(ByVal hHook As Long, ByVal ncode As Long, _
ByVal wParam As Long, lParam As Any) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
Private Const WH_KEYBOARD As Long = 2
Private Hook As Long
Public F12UpLast As Boolean

Public Sub HookKeyboard()
Hook = SetWindowsHookEx(WH_KEYBOARD, _
AddressOf KeyboardProc, App.hInstance, App.ThreadID)
End Sub

Public Sub UnHookKeyboard()
UnhookWindowsHookEx Hook
End Sub

Public Function KeyboardProc(ByVal ncode As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
If ncode >= 0 Then
If (wParam And &HFF) = vbKeyF12 Then
If (lParam And &H80000000) <> 0 Then
F12UpLast = True ' an "up" event
End If
End If
CallNextHookEx Hook, ncode, wParam, ByVal lParam
' I normally do the following to signal that we're
' done, but doing so prevents the Form KeyPfreview
' from working so I've omitted it
'KeyboardProc = -1 ' we're done here (omitted)
Else
KeyboardProc = CallNextHookEx(Hook, ncode, _
wParam, ByVal lParam)
End If
End Function
' *** END OF MODULE CODE ***





.