' ################################################################################################################################################################
' qb64_keypress_detection_test_v7.bas
' ################################################################################################################################################################
' A little script to show which keycodes are detected for the different keys
' on the keyboard using 3 different methods (_KEYDOWN, _KEYHIT, _BUTTON).
' While none of them seems to be able to detect every key, _BUTTON catches
' most of them (except for F10 and right/left ALT). So I will use _BUTTON
' to catch most of the codes, and _KEYDOWN to detect F10, and _KEYHIT for ALT.
' Here are the results for each method, compiled here in a handy table for you:
' Key _BUTTON _KEYDOWN _KEYHIT
' --------------------- ----------- -------- -----------------------------------------------------
' Esc 2 27 27
' F1 60 15104 15104
' F2 61 15360 15360
' F3 62 15616 15616
' F4 63 15872 15872
' F5 64 16128 16128
' F6 65 16384 16384
' F7 66 16640 16640
' F8 67 16896 16896
' F9 68 17152 17152
' F10 ? 17408 17408
' F11 88 ? -31488
' F12 89 ? -31232
' SysReq (Print Screen) ? ? (-44 on press/release, seems to slow down PC)
' ScrL (Scroll Lock) 71 ? (-145 on press/release, seems to slow down PC)
' Pause / Break ? ? (31053 momentarily on pressing another key)
' ~ 42 96 96
' 1! 3 49 49
' 2@ 4 50 50
' 3# 5 51 51
' 4$ 6 52 52
' 0.05 7 53 53
' 6^ 8 54 54
' 7& 9 55 55
' 8* 10 56 56
' 9( 11 57 57
' 0) 12 48 48
' -_ 13 45 45
' =+ 14 61 61
' BkSp 15 8 8
' Ins 339 20992 20992
' Home 328 18176 18176
' PgUp 330 18688 18688
' Del 340 21248 21248
' End 336 20224 20224
' PgDn 338 20736 20736
' NumLock 326 ? 30772 (flip flops with -30772 on release, -144 after)
' KEYPAD / 310 (47) 47
' KEYPAD * 56 (42) 42
' KEYPAD - 75 (45) 45
' KEYPAD 7/Home 72 18176 18176
' KEYPAD 8 Up 73 18432 18432
' KEYPAD 9 PgUp 74 18688 18688
' KEYPAD + 79 (43) 43
' KEYPAD 4 Left 76 19200 19200
' KEYPAD 5 77 ? ? (-12 after release)
' KEYPAD 6 Right 78 19712 19712
' KEYPAD 1 End 80 20224 20224
' KEYPAD 2 Down 81 20480 20480
' KEYPAD 3 PgDn 82 20736 20736
' KEYPAD ENTER 285 (13) 13
' KEYPAD 0 Ins 83 20992 20992
' KEYPAD . Del 84 21248 21248
' Tab 16 9 9
' Q 17 113 113
' W 18 119 119
' E 19 101 101
' R 20 114 114
' T 21 116 116
' Y 22 121 121
' U 23 117 117
' I 24 105 105
' O 25 111 111
' P 26 112 112
' [{ 27 91 91
' ]} 28 93 93
' \| 44 92 92
' Caps Lock 59 ? 30771 (flip flops with -30771 on release, -20 after)
' A 31 97 97
' S 32 115 115
' D 33 100 100
' F 34 102 102
' G 35 103 103
' H 36 104 104
' J 37 106 106
' K 38 107 107
' L 39 108 108
' ;: 40 59 59
' '" 41 39 39
' Enter 29 13 13
' Left Shift 43 ? -30768 (-16 on release)
' Shift (44 or 55) ? (-30768 or -30769)
' Z 45 22 22
' X 46 120 120
' C 47 99 99
' V 48 118 118
' B 49 98 98
' N 50 110 110
' M 51 109 109
' ,< 52 44 44
' .> 53 46 46
' /? 54 47 47
' Right Shift 55 ? -30769 (-16 on release)
' Up 329 18432 18432
' Left 332 19200 19200
' Down 337 20480 20480
' Right 334 19712 19712
' Left Ctrl 30 ? -30766 (-17 on release)
' Ctrl (30 or 286) ? (-30766 or -30767)
' Left Win 348 ? ? (-91 after release)
' Left Alt ? ? -30764 (-18 on release)
' Alt ? ? (-30764 or -30765)
' Spacebar 58 32 32
' Right Alt ? ? -30765 (-18 on release)
' Right Win 349 ? ? (-92 after release)
' Menu 350 ? ? (-93 after release)
' Right Ctrl 286 ? -30767 (-17 on release)
' =============================================================================
' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
' boolean constants
' =============================================================================
' GLOBAL VARIABLES
' =============================================================================
' INITIALIZE
' =============================================================================
' RUN TEST
main ProgramName$
' =============================================================================
' FINISH
SYSTEM ' return control to the operating system PRINT ProgramName$
+ " finished."
' /////////////////////////////////////////////////////////////////////////////
PRINT "Test of different methods of detecting keypresses" PRINT "1. Test using _KEYDOWN" PRINT "2. Test using _KEYHIT" PRINT "3. Test using _DEVICE commands" PRINT "4. Enumerate _DEVICES" PRINT "What to do ('q' to exit)"
KeyboardKeydownTest
KeyboardKeyhitTest
KeyboardDeviceTest
EnumerateDevices
' /////////////////////////////////////////////////////////////////////////////
' MOSTLY WORKS TO RETURN KEYHIT and KEYDOWN Codes listed at
' https://www.qb64.org/wiki/Keyboard_scancodes#KEYHIT_and_KEYDOWN_Codes
' However does not seem to detect:
' F11
' F12
' SysReq (Print Screen)
' ScrL (Scroll Lock)
' Pause / Break
' NumLock
' KEYPAD 5
' Caps Lock
' Left Shift
' Shift
' Right Shift
' Left Ctrl
' Ctrl
' Left Win
' Left Alt
' Alt
' Right Alt
' Right Win
' Menu
' Right Ctrl
' Mouse Left
' Mouse Middle
' Mouse Right
' KEYPAD ENTER returns same code as regular ENTER key (13)
' KEYPAD "-" returns same code as regular "-" key (45)
' KEYPAD "/" returns same code as regular enter key (47)
PRINT "Press a key to see what _KEYDOWN code is detetected." PRINT "(Press <ESC> to exit)."
iLastPressed = -1
' If the last key pressed is still held down, don't keep printing the code
IF (iLoop
<> iLastPressed
) THEN 'IF _KEYDOWN(iLoop) THEN
PRINT "Press a key to see what _KEYDOWN code is detetected." PRINT "Detected key press with _KEYDOWN(" + STR$(iLoop
) + ") = " + STR$(iCode
) PRINT "(Press <ESC> to exit)." iLastPressed = iLoop
' If last key is released, clear the code so it can be pressed again:
iLastPressed = -1
'_LIMIT 100
' /////////////////////////////////////////////////////////////////////////////
PRINT "Press a key to see what _KEYHIT code is detetected." PRINT "(Press <ESC> to exit)."
iLastPressed = 0
iLastPressed = iCode
' positive value means key pressed
sMessage = "Detected key pressed with _KEYHIT = " + cstr$(iCode)
' negative value means key released
sMessage = "Detected key released with _KEYHIT = " + cstr$(iCode)
iCode = -iCode ' get code of key released
IF iCode
< 256 THEN ' ASCII code values sMessage = sMessage + ", ASCII"
sMessage
= sMessage
+ " " + CHR$(34) + CHR$(iCode
) + CHR$(34) sMessage = sMessage + " (UNPRINTABLE)"
sMessage
= sMessage
+ ", 2-BYTE-COMBO (" + cstr$
(iCode
AND 255) + "," + cstr$
(iCode \
256) + ")" iKey = iCode \ 256
sMessage
= sMessage
+ " " + CHR$(34) + CHR$(iKey
) + CHR$(34) ELSEIF iCode
> 99999 AND iCode
< 200000 THEN ' QB64 Virtual Key codes sMessage = sMessage + ", QB64 SDL Virtual Key code (" + cstr$(iCode - 100000) + ")"
sMessage = sMessage + ", QB64 VK code (" + cstr$(iCode - 200000) + ")"
ELSEIF iCode
>= &H40000000 THEN ' Unicode values (IME Input mode) PRINT "IME input mode, UNICODE (" + cstr$
(iCode
- &H40000000) + "0x" + HEX$(iCode
- &H40000000) + ")" ' The MKL$ function encodes a LONG numerical value into a 4-byte ASCII STRING value.
sMessage = sMessage + " " + z$ + z$ + z$
PRINT "Press a key to see what _KEYHIT code is detetected." PRINT "(Press <ESC> to exit)." '_LIMIT 100
' /////////////////////////////////////////////////////////////////////////////
'DEVICES Button
'_LASTBUTTON(1) keyboards will normally return 512 buttons. One button is read per loop through all numbers.
'_BUTTONCHANGE(number) returns -1 when pressed, 1 when released and 0 when there is no event since the last read.
'_BUTTON(number) returns -1 when a button is pressed and 0 when released
' Detects most keys (where the codes are documented?)
' However, does not seem to detect:
' F10
' Alt
' Left Alt
' Right Alt
' Print Screen
' Pause/Break
PRINT "Press a key to see what _BUTTON code is detetected." PRINT "(Press <ESC> to exit)."
iLastPressed = -1
' Detect changed key state
' If the last key pressed is still held down, don't keep printing the code
IF (iLoop
<> iLastPressed
) THEN PRINT "Press a key to see what _BUTTON code is detetected." PRINT "Detected key press with _BUTTON(" + STR$(iLoop
) + ") = " + STR$(iCode
) PRINT "(Press <ESC> to exit)." iLastPressed = iLoop
' If last key is released, clear the code so it can be pressed again:
iLastPressed = -1
'_LIMIT 100
' /////////////////////////////////////////////////////////////////////////////
' Same as QB64's str$ function, except removes the annoying space that
' str$ prepends to the result.
' For example:
' PRINT CHR$(34) + STR$(5) + CHR$(34)
' outputs
' " 5"
' If you do a lot of str$, you find yourself having to use ltrim$ a lot,
' which can make your code harder to read.
' With this function, something that would look like
' sRightCount = LEFT$(LTRIM$(RTRIM$(STR$(arrInfo(iIndex).RightCount))) + STRING$(iLen, " "), iLen)
' becomes easier to read:
' sRightCount = LEFT$(cstr$(arrInfo(iIndex).RightCount) + STRING$(iLen, " "), iLen)
' And cstr is easy to remember for those familiar with vbscript/VBA/VB6/ASP.
' /////////////////////////////////////////////////////////////////////////////
SUB WaitForKey
(prompt$
, KeyCode&
, DelaySeconds%
) ' SHOW PROMPT (IF SPECIFIED)
' WAIT FOR KEY
' PAUSE AFTER (IF SPECIFIED)
' /////////////////////////////////////////////////////////////////////////////
' Example: Checking for the system's input devices.
' _DEVICES FUNCTION (QB64 REFERENCE)
' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/wiki/index_title_DEVICES/
'
' The _DEVICES function returns the number of INPUT devices on your computer
' including keyboard, mouse and game devices.
'
' Syntax:
'
' device_count% = _DEVICES
'
' Returns the number of devices that can be listed separately with the _DEVICE$
' function by the device number.
' Devices include keyboard, mouse, joysticks, game pads and multiple stick game
' controllers.
' Note: This function MUST be read before trying to use the _DEVICE$,
' _DEVICEINPUT or _LAST control functions!
' Note: The STRIG/STICK commands won't read from the keyboard
' or mouse device the above example lists.
devices%
= _DEVICES ' MUST be read in order for other 2 device functions to work!
PRINT "Total devices found: ";
STR$(devices%
) FOR iLoop%
= 1 TO devices%
iLen = 4
PRINT "PRESS <ESC> TO CONTINUE"