Author Topic: key code test utility v1-00 (get codes for _KEYDOWN, _KEYHIT, _BUTTON)  (Read 4203 times)

0 Members and 1 Guest are viewing this topic.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Here's a little utility that I found helpful in finding out keycodes on the spot.
Contains examples of reading the keyboard with _KEYDOWN, _KEYHIT, and _BUTTON (device) methods.
I figured I'd share it in case it helps someone...

Code: QB64: [Select]
  1. ' ################################################################################################################################################################
  2. ' Keycode detection test
  3. '
  4. ' CHANGE LOG:
  5. ' Date         Who                What
  6. ' 12/16/2020   madscijr           completed mostly working stable version 0.70
  7. ' 01/08/2022   madscijr           updated so ESC+ENTER exits each test, added change log + cleaned up for release
  8.  
  9. ' DESCRIPTION:
  10. ' A little script to show which keycodes are detected for the different keys
  11. ' on the keyboard using 3 different methods (_KEYDOWN, _KEYHIT, _BUTTON).
  12. ' While none of them seems to be able to detect every key, _BUTTON catches
  13. ' most of them (except for F10 and right/left ALT). So I will use _BUTTON
  14. ' to catch most of the codes, and _KEYDOWN to detect F10, and _KEYHIT for ALT.
  15.  
  16. ' Here are the results for each method, compiled here in a handy table for you:
  17.  
  18. ' Key                     _BUTTON       _KEYDOWN       _KEYHIT
  19. ' ---------------------   -----------   --------       -----------------------------------------------------
  20. ' Esc                     2             27             27
  21. ' F1                      60            15104          15104
  22. ' F2                      61            15360          15360
  23. ' F3                      62            15616          15616
  24. ' F4                      63            15872          15872
  25. ' F5                      64            16128          16128
  26. ' F6                      65            16384          16384
  27. ' F7                      66            16640          16640
  28. ' F8                      67            16896          16896
  29. ' F9                      68            17152          17152
  30. ' F10                     ?             17408          17408
  31. ' F11                     88            ?              -31488
  32. ' F12                     89            ?              -31232
  33. ' SysReq (Print Screen)   ?             ?              (-44 on press/release, seems to slow down PC)
  34. ' ScrL (Scroll Lock)      71            ?              (-145 on press/release, seems to slow down PC)
  35. ' Pause / Break           ?             ?              (31053 momentarily on pressing another key)
  36. ' ~                       42            96             96
  37. ' 1!                      3             49             49
  38. ' 2@                      4             50             50
  39. ' 3#                      5             51             51
  40. ' 4$                      6             52             52
  41. ' 0.05                    7             53             53
  42. ' 6^                      8             54             54
  43. ' 7&                      9             55             55
  44. ' 8*                      10            56             56
  45. ' 9(                      11            57             57
  46. ' 0)                      12            48             48
  47. ' -_                      13            45             45
  48. ' =+                      14            61             61
  49. ' BkSp                    15            8              8
  50. ' Ins                     339           20992          20992
  51. ' Home                    328           18176          18176
  52. ' PgUp                    330           18688          18688
  53. ' Del                     340           21248          21248
  54. ' End                     336           20224          20224
  55. ' PgDn                    338           20736          20736
  56. ' NumLock                 326           ?              30772 (flip flops with -30772 on release, -144 after)
  57. ' KEYPAD /                310           (47)           47
  58. ' KEYPAD *                56            (42)           42
  59. ' KEYPAD -                75            (45)           45
  60. ' KEYPAD 7/Home           72            18176          18176
  61. ' KEYPAD 8 Up             73            18432          18432
  62. ' KEYPAD 9 PgUp           74            18688          18688
  63. ' KEYPAD +                79            (43)           43
  64. ' KEYPAD 4 Left           76            19200          19200
  65. ' KEYPAD 5                77            ?              ? (-12 after release)
  66. ' KEYPAD 6 Right          78            19712          19712
  67. ' KEYPAD 1 End            80            20224          20224
  68. ' KEYPAD 2 Down           81            20480          20480
  69. ' KEYPAD 3 PgDn           82            20736          20736
  70. ' KEYPAD ENTER            285           (13)           13
  71. ' KEYPAD 0 Ins            83            20992          20992
  72. ' KEYPAD . Del            84            21248          21248
  73. ' Tab                     16            9              9
  74. ' Q                       17            113            113
  75. ' W                       18            119            119
  76. ' E                       19            101            101
  77. ' R                       20            114            114
  78. ' T                       21            116            116
  79. ' Y                       22            121            121
  80. ' U                       23            117            117
  81. ' I                       24            105            105
  82. ' O                       25            111            111
  83. ' P                       26            112            112
  84. ' [{                      27            91             91
  85. ' ]}                      28            93             93
  86. ' \|                      44            92             92
  87. ' Caps Lock               59            ?              30771 (flip flops with -30771 on release, -20 after)
  88. ' A                       31            97             97
  89. ' S                       32            115            115
  90. ' D                       33            100            100
  91. ' F                       34            102            102
  92. ' G                       35            103            103
  93. ' H                       36            104            104
  94. ' J                       37            106            106
  95. ' K                       38            107            107
  96. ' L                       39            108            108
  97. ' ;:                      40            59             59
  98. ' '"                      41            39             39
  99. ' Enter                   29            13             13
  100. ' Left Shift              43            ?              -30768 (-16 on release)
  101. ' Shift                   (44 or 55)    ?              (-30768 or -30769)
  102. ' Z                       45            22             22
  103. ' X                       46            120            120
  104. ' C                       47            99             99
  105. ' V                       48            118            118
  106. ' B                       49            98             98
  107. ' N                       50            110            110
  108. ' M                       51            109            109
  109. ' ,<                      52            44             44
  110. ' .>                      53            46             46
  111. ' /?                      54            47             47
  112. ' Right Shift             55            ?              -30769 (-16 on release)
  113. ' Up                      329           18432          18432
  114. ' Left                    332           19200          19200
  115. ' Down                    337           20480          20480
  116. ' Right                   334           19712          19712
  117. ' Left Ctrl               30            ?              -30766 (-17 on release)
  118. ' Ctrl                    (30 or 286)   ?              (-30766 or -30767)
  119. ' Left Win                348           ?              ? (-91 after release)
  120. ' Left Alt                ?             ?              -30764 (-18 on release)
  121. ' Alt                     ?             ?              (-30764 or -30765)
  122. ' Spacebar                58            32             32
  123. ' Right Alt               ?             ?              -30765 (-18 on release)
  124. ' Right Win               349           ?              ? (-92 after release)
  125. ' Menu                    350           ?              ? (-93 after release)
  126. ' Right Ctrl              286           ?              -30767 (-17 on release)
  127.  
  128. ' =============================================================================
  129. ' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
  130.  
  131. ' boolean constants
  132. Const FALSE = 0
  133. Const TRUE = Not FALSE
  134.  
  135. ' =============================================================================
  136. ' GLOBAL VARIABLES
  137. Dim Shared m_ProgramPath$: m_ProgramPath$ = Left$(Command$(0), _InStrRev(Command$(0), "\"))
  138. Dim Shared m_ProgramName$: m_ProgramName$ = Mid$(Command$(0), _InStrRev(Command$(0), "\") + 1)
  139. Dim Shared m_VersionInfo$: m_VersionInfo$ = "1.00"
  140.  
  141. ' =============================================================================
  142. ' RUN TEST
  143. main
  144.  
  145. ' =============================================================================
  146. ' FINISH
  147. System ' return control to the operating system
  148. Print m_ProgramName$ + " finished."
  149.  
  150. ' /////////////////////////////////////////////////////////////////////////////
  151.  
  152. Sub main
  153.     Dim in$: in$ = ""
  154.     Do
  155.         Cls
  156.         Print m_ProgramName$
  157.         Print
  158.         Print "Keycode Detection Test " + m_VersionInfo$
  159.         Print "by Softintheheadware (Jan, 2022)"
  160.         Print
  161.         Print "Test of different methods of detecting keypresses"
  162.         Print
  163.         Print "1. Test using _KEYDOWN"
  164.         Print
  165.         Print "2. Test using _KEYHIT"
  166.         Print
  167.         Print "3. Test using _DEVICE commands"
  168.         Print
  169.         Print "4. Enumerate _DEVICES"
  170.         Print
  171.         Print "What to do ('q' to exit)"
  172.  
  173.         Input in$: in$ = LCase$(Left$(in$, 1))
  174.         If in$ = "1" Then
  175.             KeyboardKeydownTest
  176.         ElseIf in$ = "2" Then
  177.             KeyboardKeyhitTest
  178.         ElseIf in$ = "3" Then
  179.             KeyboardDeviceTest
  180.         ElseIf in$ = "4" Then
  181.             EnumerateDevices
  182.         End If
  183.     Loop Until in$ = "q"
  184.    
  185. End Sub ' main
  186.  
  187. ' /////////////////////////////////////////////////////////////////////////////
  188. ' MOSTLY WORKS TO RETURN KEYHIT and KEYDOWN Codes listed at
  189. ' https://www.qb64.org/wiki/Keyboard_scancodes#KEYHIT_and_KEYDOWN_Codes
  190.  
  191. ' However does not seem to detect:
  192. ' F11
  193. ' F12
  194. ' SysReq (Print Screen)
  195. ' ScrL (Scroll Lock)
  196. ' Pause / Break
  197. ' NumLock
  198. ' KEYPAD 5
  199. ' Caps Lock
  200. ' Left Shift
  201. ' Shift
  202. ' Right Shift
  203. ' Left Ctrl
  204. ' Ctrl
  205. ' Left Win
  206. ' Left Alt
  207. ' Alt
  208. ' Right Alt
  209. ' Right Win
  210. ' Menu
  211. ' Right Ctrl
  212. ' Mouse Left
  213. ' Mouse Middle
  214. ' Mouse Right
  215. ' KEYPAD ENTER returns same code as regular ENTER key (13)
  216. ' KEYPAD "-"   returns same code as regular "-" key (45)
  217. ' KEYPAD "/"   returns same code as regular enter key (47)
  218.  
  219. Sub KeyboardKeydownTest
  220.     Dim iLoop As Integer
  221.     Dim iCode As Integer
  222.     Dim iLastPressed As Integer ' useful for tracking key up/key down state
  223.     Dim iPreviousKey As Integer ' use to track multi-key presses, track separately than last pressed
  224.     Dim bFinished As Integer
  225.    
  226.     Cls
  227.     Print "Press a key to see what _KEYDOWN code is detetected."
  228.     Print
  229.     Print
  230.     Print
  231.     Print "(Press <ESC> then <ENTER> to exit)."
  232.    
  233.     _KeyClear: _Delay 1
  234.     iLastPressed = -1
  235.     iPreviousKey = -1
  236.     bFinished = FALSE
  237.     Do
  238.         For iLoop = 1 To 32767
  239.             iCode = _KeyDown(iLoop)
  240.            
  241.             ' If the last key pressed is still held down, don't keep printing the code
  242.             If (iLoop <> iLastPressed) Then
  243.                 'IF _KEYDOWN(iLoop) THEN
  244.                 If iCode = TRUE Then
  245.                    
  246.                     ' Quit if user pressed Enter right after Esc
  247.                     If iLoop = 13 Then
  248.                         If iPreviousKey = 27 Then
  249.                             bFinished = TRUE
  250.                             Exit For
  251.                         End If
  252.                     End If
  253.                    
  254.                     Cls
  255.                     Print "Press a key to see what _KEYDOWN code is detetected."
  256.                     Print
  257.                     Print "Detected key press with _KEYDOWN(" + Str$(iLoop) + ") = " + Str$(iCode)
  258.                     Print
  259.                     Print "(Press <ESC> then <ENTER> to exit)."
  260.                    
  261.                     iLastPressed = iLoop
  262.                     iPreviousKey = iLoop
  263.                 End If
  264.                
  265.             Else
  266.                 ' If last key is released, clear the code so it can be pressed again:
  267.                 If iCode = FALSE Then
  268.                     iLastPressed = -1
  269.                 End If
  270.             End If
  271.         Next iLoop
  272.        
  273.         '_LIMIT 100
  274.         'LOOP UNTIL _KEYDOWN(27)
  275.     Loop Until bFinished = TRUE
  276.    
  277.     _KeyClear
  278. End Sub ' KeyboardKeydownTest
  279.  
  280. ' /////////////////////////////////////////////////////////////////////////////
  281.  
  282. Sub KeyboardKeyhitTest
  283.     Dim iLoop As Integer
  284.     Dim iCode As Integer
  285.     Dim iLastPressed As Integer
  286.     Dim iKey As Integer
  287.     Dim sMessage As String
  288.     Dim z$
  289.     Dim bFinished As Integer
  290.    
  291.     Cls
  292.     Print "Press a key to see what _KEYHIT code is detetected."
  293.     Print
  294.     Print
  295.     Print
  296.     Print "(Press <ESC> then <ENTER> to exit)."
  297.  
  298.     _KeyClear: _Delay 1
  299.     iLastPressed = 0
  300.     bFinished = FALSE
  301.     Do
  302.         iCode = _KeyHit
  303.         If iCode <> 0 Then
  304.             If iLastPressed <> iCode Then
  305.                
  306.                 If iCode > 0 Then
  307.                     ' Quit if user pressed Enter right after Esc
  308.                     If iCode = 13 Then
  309.                         If iLastPressed = 27 Then
  310.                             bFinished = TRUE
  311.                             Exit Do
  312.                         End If
  313.                     End If
  314.                    
  315.                     ' positive value means key pressed
  316.                     sMessage = "Detected key  pressed with _KEYHIT = " + cstr$(iCode)
  317.                 Else
  318.                     ' negative value means key released
  319.                     sMessage = "Detected key released with _KEYHIT = " + cstr$(iCode)
  320.                     iCode = -iCode ' get code of key released
  321.                 End If
  322.  
  323.                 If iCode < 256 Then ' ASCII code values
  324.                     sMessage = sMessage + ", ASCII"
  325.                     If iCode > 31 Then
  326.                         sMessage = sMessage + " " + Chr$(34) + Chr$(iCode) + Chr$(34)
  327.                     Else
  328.                         sMessage = sMessage + " (UNPRINTABLE)"
  329.                     End If
  330.                 ElseIf iCode > 255 And iCode < 65536 Then ' 2 byte key codes
  331.                     sMessage = sMessage + ", 2-BYTE-COMBO (" + cstr$(iCode And 255) + "," + cstr$(iCode \ 256) + ")"
  332.                     iKey = iCode \ 256
  333.                     If iKey > 31 And iKey < 256 Then
  334.                         sMessage = sMessage + " " + Chr$(34) + Chr$(iKey) + Chr$(34)
  335.                     End If
  336.                 ElseIf iCode > 99999 And iCode < 200000 Then ' QB64 Virtual Key codes
  337.                     sMessage = sMessage + ", QB64 SDL Virtual Key code (" + cstr$(iCode - 100000) + ")"
  338.  
  339.                 ElseIf iCode > 199999 And iCode < &H40000000 Then
  340.                     sMessage = sMessage + ", QB64 VK code (" + cstr$(iCode - 200000) + ")"
  341.  
  342.                 ElseIf iCode >= &H40000000 Then ' Unicode values (IME Input mode)
  343.                     Print "IME input mode, UNICODE (" + cstr$(iCode - &H40000000) + "0x" + Hex$(iCode - &H40000000) + ")"
  344.                     ' The MKL$ function encodes a LONG numerical value into a 4-byte ASCII STRING value.
  345.                     z$ = MKL$(iCode - &H40000000) + MKL$(0)
  346.                     sMessage = sMessage + " " + z$ + z$ + z$
  347.                 End If
  348.  
  349.                 Cls
  350.                 Print "Press a key to see what _KEYHIT code is detetected."
  351.                 Print
  352.                 Print sMessage
  353.                 Print
  354.                 Print "(Press <ESC> then <ENTER> to exit)."
  355.                
  356.                 iLastPressed = iCode
  357.             End If
  358.         End If ' iCode <> 0
  359.         '_LIMIT 100
  360.         'LOOP UNTIL _KEYDOWN(27)
  361.     Loop Until bFinished = TRUE
  362.    
  363.     _KeyClear
  364.  
  365. End Sub ' KeyboardKeyhitTest
  366.  
  367. ' /////////////////////////////////////////////////////////////////////////////
  368. 'DEVICES Button
  369. '_LASTBUTTON(1) keyboards will normally return 512 buttons. One button is read per loop through all numbers.
  370. '_BUTTONCHANGE(number) returns -1 when pressed, 1 when released and 0 when there is no event since the last read.
  371. '_BUTTON(number) returns -1 when a button is pressed and 0 when released
  372.  
  373. ' Detects most keys (where the codes are documented?)
  374. ' However, does not seem to detect:
  375. ' F10
  376. ' Alt
  377. ' Left Alt
  378. ' Right Alt
  379. ' Print Screen
  380. ' Pause/Break
  381.  
  382. Sub KeyboardDeviceTest
  383.     Dim iLoop As Integer
  384.     Dim iCode As Integer
  385.     Dim iLastPressed As Integer ' useful for tracking key up/key down state
  386.     Dim iPreviousKey As Integer ' use to track multi-key presses, track separately than last pressed
  387.     Dim bFinished As Integer
  388.    
  389.     Cls
  390.     Print "Press a key to see what _BUTTON code is detetected."
  391.     Print
  392.     Print
  393.     Print
  394.     Print "(Press <ESC> then <ENTER> to exit)."
  395.    
  396.     _KeyClear: _Delay 1
  397.     iLastPressed = -1
  398.     iPreviousKey = -1
  399.     Do
  400.         While _DeviceInput(1): Wend ' clear and update the keyboard buffer
  401.        
  402.         ' Detect changed key state
  403.         For iLoop = 1 To 512
  404.             iCode = _Button(iLoop)
  405.            
  406.             ' If the last key pressed is still held down, don't keep printing the code
  407.             If (iLoop <> iLastPressed) Then
  408.                
  409.                 If iCode <> 0 Then
  410.                     ' Quit if user pressed Enter right after Esc
  411.                     If iPreviousKey = 2 Then
  412.                         If iLoop = 29 Then
  413.                             bFinished = TRUE
  414.                             Exit For
  415.                         End If
  416.                     End If
  417.                    
  418.                     Cls
  419.                     Print "Press a key to see what _BUTTON code is detetected."
  420.                     Print
  421.                     Print "Detected key press with _BUTTON(" + Str$(iLoop) + ") = " + Str$(iCode)
  422.                     Print
  423.                     Print "(Press <ESC> then <ENTER> to exit)."
  424.                    
  425.                     iLastPressed = iLoop
  426.                     iPreviousKey = iLoop
  427.                 End If
  428.             Else
  429.                 ' If last key is released, clear the code so it can be pressed again:
  430.                 If iCode = 0 Then
  431.                     iLastPressed = -1
  432.                 End If
  433.             End If
  434.         Next iLoop
  435.        
  436.         '_LIMIT 100
  437.         'LOOP UNTIL _KEYDOWN(27)
  438.     Loop Until bFinished = TRUE
  439.    
  440.     _KeyClear
  441. End Sub ' KeyboardDeviceTest
  442.  
  443. ' /////////////////////////////////////////////////////////////////////////////
  444. ' Same as QB64's str$ function, except removes the annoying space that
  445. ' str$ prepends to the result.
  446. ' For example:
  447. '     PRINT CHR$(34) + STR$(5) + CHR$(34)
  448. ' outputs
  449. '     " 5"
  450. ' If you do a lot of str$, you find yourself having to use ltrim$ a lot,
  451. ' which can make your code harder to read.
  452. ' With this function, something that would look like
  453. '     sRightCount = LEFT$(LTRIM$(RTRIM$(STR$(arrInfo(iIndex).RightCount))) + STRING$(iLen, " "), iLen)
  454. ' becomes easier to read:
  455. '     sRightCount = LEFT$(cstr$(arrInfo(iIndex).RightCount) + STRING$(iLen, " "), iLen)
  456. ' And cstr is easy to remember for those familiar with vbscript/VBA/VB6/ASP.
  457.  
  458. Function cstr$ (myValue)
  459.     cstr$ = LTrim$(RTrim$(Str$(myValue)))
  460. End Function ' cstr$
  461.  
  462. ' /////////////////////////////////////////////////////////////////////////////
  463. ' Example: Checking for the system's input devices.
  464.  
  465. ' _DEVICES FUNCTION (QB64 REFERENCE)
  466. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/wiki/index_title_DEVICES/
  467. '
  468. ' The _DEVICES function returns the number of INPUT devices on your computer
  469. ' including keyboard, mouse and game devices.
  470. '
  471. ' Syntax:
  472. '
  473. ' device_count% = _DEVICES
  474. '
  475. ' Returns the number of devices that can be listed separately with the _DEVICE$
  476. ' function by the device number.
  477. ' Devices include keyboard, mouse, joysticks, game pads and multiple stick game
  478. ' controllers.
  479. ' Note: This function MUST be read before trying to use the _DEVICE$,
  480. ' _DEVICEINPUT or _LAST control functions!
  481.  
  482. ' Note: The STRIG/STICK commands won't read from the keyboard
  483. '       or mouse device the above example lists.
  484.  
  485. Sub EnumerateDevices
  486.     Dim devices%
  487.     Dim iLoop%
  488.     Dim sCount$
  489.     Dim iLen As Integer
  490.  
  491.     devices% = _Devices ' MUST be read in order for other 2 device functions to work!
  492.  
  493.     Cls
  494.     Print "Total devices found: "; Str$(devices%)
  495.     For iLoop% = 1 To devices%
  496.         iLen = 4
  497.         sCount$ = Left$(LTrim$(RTrim$(Str$(iLoop%))) + String$(iLen, " "), iLen)
  498.         Print sCount$ + _Device$(iLoop%) + " (" + LTrim$(RTrim$(Str$(_LastButton(iLoop%)))) + " buttons)"
  499.     Next iLoop%
  500.     Print
  501.     Print "PRESS <ESC> TO CONTINUE"
  502.     Do: Loop Until _KeyDown(27) ' leave loop when ESC key pressed
  503.     _KeyClear: '_DELAY 1
  504.  
  505. End Sub ' EnumerateDevices
  506.  
  507.  
  508.  

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: key code test utility v1-00 (get codes for _KEYDOWN, _KEYHIT, _BUTTON)
« Reply #1 on: January 08, 2022, 03:55:03 pm »
In never versions of QB64, just hit CTRL-K and then the key you want to auto-insert their keycode into your program.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: key code test utility v1-00 (get codes for _KEYDOWN, _KEYHIT, _BUTTON)
« Reply #2 on: January 08, 2022, 04:52:06 pm »
In never versions of QB64, just hit CTRL-K and then the key you want to auto-insert their keycode into your program.

Good to know, thanks.
Is that for _keydown & _keyhit or will it work for _button too?
So far I have found _button detects the most keys...

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: key code test utility v1-00 (get codes for _KEYDOWN, _KEYHIT, _BUTTON)
« Reply #3 on: January 08, 2022, 07:32:46 pm »
Man that's a timesaver, don't have to look up the arrow keys anymore.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: key code test utility v1-00 (get codes for _KEYDOWN, _KEYHIT, _BUTTON)
« Reply #4 on: January 08, 2022, 11:28:50 pm »
Man that's a timesaver, don't have to look up the arrow keys anymore.

You're welcome.  😉
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: key code test utility v1-00 (get codes for _KEYDOWN, _KEYHIT, _BUTTON)
« Reply #5 on: January 09, 2022, 03:52:35 pm »
You're welcome.  😉

Is there a list collected together somewhere of all these little timesavers, that maybe qb64 users aren't aware of?