Intercepts keyboard events before they are dispatched to the target form or control.
Sub Screen_KeyPreview(hWnd%, uMsg%, wParam%, lParam%, Cancel?)
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. |
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.
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.
Screen, KeyPress, KeyUp, KeyDown
{Created by Sjouke Hamstra; Last updated: 22/10/2014 by James Gaite}