Is there a topic the FF3 Help file that covers Key Press Trapping? I did a search on "Key Trapping" and came up empty handed. May be I am searching for the wrong term?
What I want to do is to test for the "ESC" key being pressed anywhere on a Form. Any time the "ESC" key is pressed I want it to "Set Focus" to a particular TextBox.
Also, when in a particular TextBox I want to test for the "Up" or "Down" arrow Keys being pressed and if pressed I want a particular action to occur.
Does a simple example program exist that shows how to do this sort of thing? I looked at the FF example projects and didn't see one that covered this topic.
edited 11 Jan 2010:
Added an simple example program: KeyCapture
This program will demonstrate how you can easily capture Key Presses such as ESC, ENTER, Up and DOWN arrow keys, F1 - F12 function keys. The example program was possible because of Paul's help. Hope this program will be of use to other programmers.
The link below is for a FF3 project "KeyCapture" :
That stuff is not in the FF Help file because it is standard WinAPI programming type of information. What you're asking can be broken down into two answers:
(1) Global "ESC" for a form (Note, there will need to be a control on your form that has keyboard focus in order for this to work). We add code directly to the message pump via the FF_PUMPHOOK function and catch the incoming WM_KEYDOWN message and act on it.
Function FF_PUMPHOOK( Msg As tagMsg ) As Long
' If this function returns FALSE (zero) then the processing of the regular
' FireFly message pump will continue. Returning TRUE (non-zero) will bypass
' the regular message pump.
Function = %FALSE 'return %TRUE if you need to bypass the FireFly message pump
' If you are dealing with a 'normal' OCX control then the following code will
' allow the message to be forwarded to the OCX.
#If %DEF( %USE_JOSE_INCLUDES )
#If %DEF( %USE_JOSE_OCX )
Function = OC_ForwardMessage( GetFocus(), Msg)
#EndIf
#EndIf
' Is the message going to the control on the Form that we are interested in?
If GetParent(Msg.hWnd) = HWND_FORM1 Then
' Determine if the ESC key was pressed.
Select Case Msg.Message
Case %WM_KEYDOWN
If Msg.wParam = %VK_ESCAPE Then
? "escape"
SetFocus HWND_FORM1_TEXT1
End If
End Select
End If
End Function
(2) Dealing with "UP" and "DOWN" arrows for a particular TextBox:
Function FORM1_TEXT1_WM_KEYDOWN ( _
ControlIndex As Long, _ ' index in Control Array
hWndForm As Dword, _ ' handle of Form
hWndControl As Dword, _ ' handle in Control
nVirtKey As Long, _ ' virtual key code
lKeyData As Long _ ' key data
) As Long
Select Case nVirtKey
Case %VK_UP
? "Up key pressed"
Function = %TRUE ' prevent key from making it to the TextBox
Case %VK_DOWN
? "Down key pressed"
Function = %TRUE ' prevent key from making it to the TextBox
End Select
End Function
Thanks Paul
Is there a list of these %VK_ constants somewhere?
The Win-API references I have found on the web are C oriented. Is there a Win-API reference for the BASIC programmer that you would recommend?
Quote from: Marty Francom on January 08, 2010, 08:21:01 PM
Is there a list of these %VK_ constants somewhere?
Using PowerBASIC includes: WinAPI.inc
Using Jose's includes: WinUser.inc
Quote
The Win-API references I have found on the web are C oriented. Is there a Win-API reference for the BASIC programmer that you would recommend?
Not that I know of. I learned most of my stuff from reading endless posts in POFFS or on-line with the PB forums. Also, Jose's forum and website is invaluable. Over the years I have learned how to read "C" code pretty well so I can usually translate from C to PB.
Ok found them:
Here they are:
' Virtual Keys, Standard Set
%VK_LBUTTON = &H01
%VK_RBUTTON = &H02
%VK_CANCEL = &H03
%VK_MBUTTON = &H04 ' NOT contiguous with L RBUTTON
%VK_XBUTTON1 = &H05 ' NOT contiguous with L & RBUTTON
%VK_XBUTTON2 = &H06 ' NOT contiguous with L & RBUTTON
%VK_BACK = &H08
%VK_TAB = &H09
%VK_LINEFEED = &H0A
%VK_CLEAR = &H0C
%VK_RETURN = &H0D
%VK_SHIFT = &H10
%VK_CONTROL = &H11
%VK_MENU = &H12
%VK_PAUSE = &H13
%VK_CAPITAL = &H14
%VK_KANA = &H15
%VK_HANGEUL = &H15 ' old name - should be here for compatibility
%VK_HANGUL = &H15
%VK_JUNJA = &H17
%VK_FINAL = &H18
%VK_HANJA = &H19
%VK_KANJI = &H19
%VK_ESCAPE = &H1B
%VK_CONVERT = &H1C
%VK_NONCONVERT = &H1D
%VK_ACCEPT = &H1E
%VK_MODECHANGE = &H1F
%VK_SPACE = &H20
%VK_PGUP = &H21
%VK_PRIOR = &H21
%VK_NEXT = &H22
%VK_PGDN = &H22
%VK_END = &H23
%VK_HOME = &H24
%VK_LEFT = &H25
%VK_UP = &H26
%VK_RIGHT = &H27
%VK_DOWN = &H28
%VK_SELECT = &H29
%VK_PRINT = &H2A
%VK_EXECUTE = &H2B
%VK_SNAPSHOT = &H2C
%VK_INSERT = &H2D
%VK_DELETE = &H2E
%VK_HELP = &H2F
%VK_0 = &H30
%VK_1 = &H31
%VK_2 = &H32
%VK_3 = &H33
%VK_4 = &H34
%VK_5 = &H35
%VK_6 = &H36
%VK_7 = &H37
%VK_8 = &H38
%VK_9 = &H39
%VK_A = &H41
%VK_B = &H42
%VK_C = &H43
%VK_D = &H44
%VK_E = &H45
%VK_F = &H46
%VK_G = &H47
%VK_H = &H48
%VK_I = &H49
%VK_J = &H4A
%VK_K = &H4B
%VK_L = &H4C
%VK_M = &H4D
%VK_N = &H4E
%VK_O = &H4F
%VK_P = &H50
%VK_Q = &H51
%VK_R = &H52
%VK_S = &H53
%VK_T = &H54
%VK_U = &H55
%VK_V = &H56
%VK_W = &H57
%VK_X = &H58
%VK_Y = &H59
%VK_Z = &H5A
%VK_LWIN = &H5B
%VK_RWIN = &H5C
%VK_APPS = &H5D
%VK_SLEEP = &H5F
%VK_NUMPAD0 = &H60
%VK_NUMPAD1 = &H61
%VK_NUMPAD2 = &H62
%VK_NUMPAD3 = &H63
%VK_NUMPAD4 = &H64
%VK_NUMPAD5 = &H65
%VK_NUMPAD6 = &H66
%VK_NUMPAD7 = &H67
%VK_NUMPAD8 = &H68
%VK_NUMPAD9 = &H69
%VK_MULTIPLY = &H6A
%VK_ADD = &H6B
%VK_SEPARATOR= &H6C
%VK_SUBTRACT = &H6D
%VK_DECIMAL = &H6E
%VK_DIVIDE = &H6F
%VK_F1 = &H70
%VK_F2 = &H71
%VK_F3 = &H72
%VK_F4 = &H73
%VK_F5 = &H74
%VK_F6 = &H75
%VK_F7 = &H76
%VK_F8 = &H77
%VK_F9 = &H78
%VK_F10 = &H79
%VK_F11 = &H7A
%VK_F12 = &H7B
%VK_F13 = &H7C
%VK_F14 = &H7D
%VK_F15 = &H7E
%VK_F16 = &H7F
%VK_F17 = &H80
%VK_F18 = &H81
%VK_F19 = &H82
%VK_F20 = &H83
%VK_F21 = &H84
%VK_F22 = &H85
%VK_F23 = &H86
%VK_F24 = &H87
%VK_NUMLOCK = &H90
%VK_SCROLL = &H91
' NEC PC-9800 kbd definitions
%VK_OEM_NEC_EQUAL = &H92 ' "=" key on numpad
' Fujitsu/OASYS kbd definitions
%VK_OEM_FJ_JISHO = &H92 ' "Dictionary" key
%VK_OEM_FJ_MASSHOU = &H93 ' "Unregister word" key
%VK_OEM_FJ_TOUROKU = &H94 ' "Register word" key
%VK_OEM_FJ_LOYA = &H95 ' "Left OYAYUBI" key
%VK_OEM_FJ_ROYA = &H96 ' "Right OYAYUBI" key
' VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys.
' Used only as parameters to GetAsyncKeyState() and GetKeyState().
' No other API or message will distinguish left and right keys in this way.
%VK_LSHIFT = &HA0
%VK_RSHIFT = &HA1
%VK_LCONTROL = &HA2
%VK_RCONTROL = &HA3
%VK_LMENU = &HA4
%VK_RMENU = &HA5
%VK_BROWSER_BACK = &HA6
%VK_BROWSER_FORWARD = &HA7
%VK_BROWSER_REFRESH = &HA8
%VK_BROWSER_STOP = &HA9
%VK_BROWSER_SEARCH = &HAA
%VK_BROWSER_FAVORITES = &HAB
%VK_BROWSER_HOME = &HAC
%VK_VOLUME_MUTE = &HAD
%VK_VOLUME_DOWN = &HAE
%VK_VOLUME_UP = &HAF
%VK_MEDIA_NEXT_TRACK = &HB0
%VK_MEDIA_PREV_TRACK = &HB1
%VK_MEDIA_STOP = &HB2
%VK_MEDIA_PLAY_PAUSE = &HB3
%VK_LAUNCH_MAIL = &HB4
%VK_LAUNCH_MEDIA_SELECT = &HB5
%VK_LAUNCH_APP1 = &HB6
%VK_LAUNCH_APP2 = &HB7
%VK_OEM_1 = &HBA ' ";:" for US
%VK_OEM_PLUS = &HBB ' "+" any country
%VK_OEM_COMMA = &HBC ' "," any country
%VK_OEM_MINUS = &HBD ' "-" any country
%VK_OEM_PERIOD = &HBE ' "." any country
%VK_OEM_2 = &HBF ' "/?" for US
%VK_OEM_3 = &HC0 ' "`~" for US
%VK_OEM_4 = &HDB ' "[{" for US
%VK_OEM_5 = &HDC ' "\|" for US
%VK_OEM_6 = &HDD ' "]}" for US
%VK_OEM_7 = &HDE ' """" for US
%VK_OEM_8 = &HDF
%VK_OEM_AX = &HE1 ' "AX" key on Japanese AX kbd
%VK_OEM_102 = &HE2 ' "<>" or "\|" on RT 102-key kbd.
%VK_ICO_HELP = &HE3 ' Help key on ICO
%VK_ICO_00 = &HE4 ' 00 key on ICO
%VK_PROCESSKEY = &HE5
%VK_ICO_CLEAR = &HE6
%VK_PACKET = &HE7
' Nokia/Ericsson definitions
%VK_OEM_RESET = &HE9
%VK_OEM_JUMP = &HEA
%VK_OEM_PA1 = &HEB
%VK_OEM_PA2 = &HEC
%VK_OEM_PA3 = &HED
%VK_OEM_WSCTRL = &HEE
%VK_OEM_CUSEL = &HEF
%VK_OEM_ATTN = &HF0
%VK_OEM_FINISH = &HF1
%VK_OEM_COPY = &HF2
%VK_OEM_AUTO = &HF3
%VK_OEM_ENLW = &HF4
%VK_OEM_BACKTAB = &HF5
%VK_ATTN = &HF6
%VK_CRSEL = &HF7
%VK_EXSEL = &HF8
%VK_EREOF = &HF9
%VK_PLAY = &HFA
%VK_ZOOM = &HFB
%VK_NONAME = &HFC
%VK_PA1 = &HFD
%VK_OEM_CLEAR = &HFE
#ENDIF '#IF NOT %DEF(%NOVIRTUALKEYCODES) '-------------------------------------
Paul,
I don't see in the list a constant for the "Enter" key. I was expecting to find %VK_ENTER but did not find it. Is it listed differently.
There is one other thing I would like to do: I would like to have an "Enter" key press behave as if it were a "Tab" key press. ie: When filling in the text boxes on the screen I would like to move from TextBox to TextBox by pressing the "Enter" key.
I assume I would check for the "Enter Key" in the FF_PUMPHOOK function. But how would I tell the program to move the focus to the next Tab Order control.
I know that capturing the "Enter Key" could cause problems with multiline TextBox controls and with RichEdit Controls. Is this situation would need to be dealt with.
Quote
I was expecting to find %VK_ENTER but did not find it. Is it listed differently.
When that constant was defined, the ENTER key was labeled RETURN in the keyboards :)
Quote
' Is the message going to the control on the Form that we are interested in?
If GetParent(Msg.hWnd) = HWND_FORM1 Then
' Determine if the ESC key was pressed.
Select Case Msg.Message
Case %WM_KEYDOWN
If Msg.wParam = %VK_ESCAPE Then
? "escape"
SetFocus HWND_FORM1_TEXT1
End If
End Select
End If
Nice piece of code, Paul. Just came in handy...
Quote
I would like to have an "Enter" key press behave as if it were a "Tab" key press.
Modify the FF_PUMPHOOK from the earlier post to act on all ENTER keys being sent to any EDIT (TextBox) control:
Select Case Msg.Message
Case %WM_KEYDOWN
If Msg.wParam = %VK_RETURN Then
Static zClass As Asciiz * 50
GetClassName Msg.hWnd, zClass, SizeOf(zClass)
If UCase$(zClass) = "EDIT" Then
' change the key to be a "TAB" that should move us to the next control
Msg.wParam = %VK_TAB
End If
End If
End Select
That's works wonderfully.
Is there a way to test for a "MultiLine TextBox" and if current focus is in a
"MultiLine Textbox" then do not change %VK_RETURN to %VK_TAB so as
not to interfer with editing in a MultiLine TextBox.
I am pretty sure I need to check the TextBox's property of ES_MULTILINE I am just
not sure what the correct syntax would be.
I found that changing Enter Key press to a Tab key press does NOT interfer with editing
in an RichEdit Control. So another way to avoid this problem with multline textboxes is to use a RichEdit Control instead of multiline text boxes on the form where the Enter Key is being captured.
To test for multiline, try something like the following (not tested):
If ( GetWindowLong(hWndControl, %GWL_STYLE) And %ES_MULTILINE ) = %ES_MULTILINE Then ....
This didn't have the desired effect. This stopped converting %VK_RETURN to %VK_TAB on all TextBox's. Just wanted to prevent it on MultLine TextBoxs.
This is how I implimented it. Maybe I not implimenting it quite the way you had in mind ??
If Msg.wParam = %VK_RETURN Then
If (GetWindowLong(HWND_FORM1_TEXT20, %GWL_STYLE) And %ES_MULTILINE ) = %ES_MULTILINE Then Exit Function
Static zClass As Asciiz * 50
GetClassName Msg.hWnd, zClass, SizeOf(zClass)
If UCase$(zClass) = "EDIT" Then
' change the key to be a "TAB" that should move us to the next control
Msg.wParam = %VK_TAB
End If
End If
Is there a way to determine what the name of the current active TextBox ?
Th name of the control with focus?
I guess this is what you're looking for?
Select Case Msg.Message
Case %WM_KEYDOWN
If Msg.wParam = %VK_RETURN Then
Static zClass As Asciiz * 10
GetClassName Msg.hWnd, zClass, SizeOf(zClass)
If UCase$(zClass) = "EDIT" Then
If (GetWindowLong(Msg.hWnd, %GWL_STYLE) And %ES_MULTILINE ) <> %ES_MULTILINE Then
' change the key to be a "TAB" that show move us to the next control
Msg.wParam = %VK_TAB
End If
End If
End If
End Select
Thanks again Paul.
I added a example program, demonstarting how to use what you taught me.
Select Case Msg.Message
Case %WM_KEYDOWN
If Msg.wParam = %VK_ESCAPE Then
PostMessage (GetParent(Msg.hWnd), %WM_CLOSE, 0, 0)
End If
End Select
This seems to close all child forms except for the main form (non-MDI) when there are no controls. How do you trap ESC on the main form that has no controls or any form without controls and post a WM_CLOSE?
QuoteWhen that constant was defined, the ENTER key was labeled RETURN in the keyboards
Remember the old Typewriter Days and the
Carriage Return? Thus the name
RETURN key!