Screen_KeyPreview Event

Purpose

Intercepts keyboard events before they are dispatched to the target form or control.

Syntax

Sub Screen_KeyPreview(hWnd%, uMsg%, wParam%, lParam%, Cancel?)

Description

The event is invoked before GFA-BASIC 32 or Windows handles the key press. The event provides a central place to filter key events or to handle keyboard events in a custom manner (to create an editor, or something similar).

You can use this event to create a keyboard-handling procedure for an application. For example, when an application uses function keys, you'll want to process the keystrokes at the application level rather than writing code for each form or control that might receive keystroke events.

The event parameters:

hWnd% Windows handle of the message
uMsg% The window message number (WM_CHAR, WM_DEADCHAR, WM_KEYDOWN, WM_KEYUP, WM_SYSCHAR, WM_SYSDEADCHAR, WM_SYSKEYDOWN or WM_SYSKEYUP).
wParam% The key code or ASCII value, dependant upon the window message (see Key Codes and ASCII Values).
lParam% Extended key information dependant upon the window message.
Cancel? Return value. Set to True when the keyboard message is to be ignored.

Example

Debug.Show

OpenW 1, 0, 0, 200, 200

Do

Sleep

Until Win_1 Is Nothing

 

Sub Screen_KeyPreview(hWnd%, Msg%, wParam%, lParam%, Cancel?)

' Display keyboard message values.

' Don't use a MsgBox or the like.

Debug Hex(hWnd)` Hex(Msg)` Hex(wParam)` Hex(lParam)

' Determine the (child) window the message is for.

If hWnd = Win_1.hWnd

' Do your thing

If Msg = WM_KEYDOWN && wParam = VK_F1

Debug "Filtering F1 for Win_1"

Cancel? = True

EndIf

' or alternative:

Else If Form(hWnd) Is Win_1

Else

Local Object Obj

Set Obj = OCX(hWnd)

' Test for Nothing or use Try/Catch

If IsNothing(Obj) Then

Exit Sub

EndIf

' Filter TAB for all TextBoxes (Example)

If TypeOf(Obj) Is TextBox && _

Msg = WM_KEYDOWN && wParam = VK_TAB

Cancel? = True

EndIf

' Test for a message for a child control

If Obj.Parent Is Win_1

Debug "ChildOcx of Win_1"

End If

EndIf

End Sub

If the control receiving the key press is a ComboBox, the return value for Typename(OCX(hWnd%)) in this example will return 'Nothing' as the handle refers to the edit box within the ComboBox; to get the actual ComboBox, use OCX(GetParent(hWnd%)) instead. However, if OCX() produces a recognised type, GetParent() can invoke a Type Error so it is advisable to use the obj.Parent property in that instance.

Remarks

Don't use a MsgBox, Alert, Input or some other dialog box inside the Screen_KeyPreview event sub. All keyboard events arrive in this sub, so that a recursive call of Screen_KeyPreview is more than likely.

Also, don't respond to messages in this event sub. The only thing that is allowed is to cancel a keyboard message by setting Cancel? to True. SetFocus is allowed, but only with one of the corresponding messages, for instance with WM_KEYDOWN, but not with WM_KEYUP, or the other way round.

When the Shift, Control, Alt and/or Alt Gr keys are pressed, a new event is created; however, any charcter keys entered while they are pressed do not always carry details of the state of these keys. It is possible to set up Static booleans to track the shift key state although it is more reliable to query the Screen.ShiftKeys property when necessary.

See Also

Screen, KeyPress, KeyUp, KeyDown

{Created by Sjouke Hamstra; Last updated: 22/10/2014 by James Gaite}