Code archives/User Input/Windows-style Keyboard Interface
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| If you want to see an example, copy the program below, then uncomment the short "example" program at the very bottom. To use this in your program, Include() this library, and call at least one of the "register" routines, then call KEY_GetKey() just like you'd use Blitz's builtin GetKey(). Warning: if you don't call any of the "register" routines, KEY_GetKey() will never return a keystroke! Differences from how Windows handles the keyboard: 1. If the user presses an unrecognized key while holding down a recognized one, the repeating effect will not be stopped. To fix this, register each unused key on the keyboard with an ASCII value of 0. 2. Windows allows you to release shift and continue repeating, but pressing shift will stop repeating. This function differs from Windows's behaviour in that it does not stop repeating if shift is pressed (or released, for that matter). Emulating this quirk would be easy, but I think it's stupid so I didn't. | |||||
Type KEY_Global
Field scancode_to_ascii.KEY_info[255]
Field repeat_initial_delay
Field repeat_subsequent_delay
Field repeat_timer
Field depressed_key.KEY_info
End Type
Global KEY_Global.KEY_Global = New KEY_Global
KEY_Global\repeat_initial_delay = 750
KEY_Global\repeat_subsequent_delay = 75
Type KEY_info
Field scancode
Field ascii_plain ; lowercase
Field ascii_shift ; uppercase
End Type
;--------------------------------------------------------
Function KEY_register_keyinfo(scancode, ascii_plain=0, ascii_shift=0)
;--------------------------------------------------------
KEY_Global\scancode_to_ascii[scancode] = New KEY_info
KEY_Global\scancode_to_ascii[scancode]\scancode = scancode
KEY_Global\scancode_to_ascii[scancode]\ascii_plain = ascii_plain
KEY_Global\scancode_to_ascii[scancode]\ascii_shift = ascii_shift
End Function
;--------------------------------------------------------
Function KEY_register_printable_keys()
;--------------------------------------------------------
KEY_register_keyinfo( 41, 96, 126) ; ` and ~
KEY_register_keyinfo( 2, 49, 33) ; 1 and !
KEY_register_keyinfo( 3, 50, 64) ; 2 and @
KEY_register_keyinfo( 4, 51, 35) ; 3 and #
KEY_register_keyinfo( 5, 52, 36) ; 4 and $
KEY_register_keyinfo( 6, 53, 37) ; 5 and %
KEY_register_keyinfo( 7, 54, 94) ; 6 and ^
KEY_register_keyinfo( 8, 55, 38) ; 7 and &
KEY_register_keyinfo( 9, 56, 42) ; 8 and *
KEY_register_keyinfo( 10, 57, 40) ; 9 and (
KEY_register_keyinfo( 11, 48, 41) ; 0 and )
KEY_register_keyinfo( 12, 45, 95) ; - and _
KEY_register_keyinfo( 13, 61, 43) ; = and +
KEY_register_keyinfo( 16, 113, 81) ; q and Q
KEY_register_keyinfo( 17, 119, 87) ; w and W
KEY_register_keyinfo( 18, 101, 69) ; e and E
KEY_register_keyinfo( 19, 114, 82) ; r and R
KEY_register_keyinfo( 20, 116, 84) ; t and T
KEY_register_keyinfo( 21, 121, 89) ; y and Y
KEY_register_keyinfo( 22, 117, 85) ; u and U
KEY_register_keyinfo( 23, 105, 73) ; i and I
KEY_register_keyinfo( 24, 111, 79) ; o and O
KEY_register_keyinfo( 25, 112, 80) ; p and P
KEY_register_keyinfo( 26, 91, 123) ; [ and {
KEY_register_keyinfo( 27, 93, 125) ; ] and }
KEY_register_keyinfo( 43, 92, 124) ; \ and |
KEY_register_keyinfo( 30, 97, 65) ; a and A
KEY_register_keyinfo( 31, 115, 83) ; s and S
KEY_register_keyinfo( 32, 100, 68) ; d and D
KEY_register_keyinfo( 33, 102, 70) ; f and F
KEY_register_keyinfo( 34, 103, 71) ; g and G
KEY_register_keyinfo( 35, 104, 72) ; h and H
KEY_register_keyinfo( 36, 106, 74) ; j and J
KEY_register_keyinfo( 37, 107, 75) ; k and K
KEY_register_keyinfo( 38, 108, 76) ; l and L
KEY_register_keyinfo( 39, 59, 58) ; ; and :
KEY_register_keyinfo( 40, 39, 34) ; ' and "
KEY_register_keyinfo( 44, 122, 90) ; z and Z
KEY_register_keyinfo( 45, 120, 88) ; x and X
KEY_register_keyinfo( 46, 99, 67) ; c and C
KEY_register_keyinfo( 47, 118, 86) ; v and V
KEY_register_keyinfo( 48, 98, 66) ; b and B
KEY_register_keyinfo( 49, 110, 78) ; n and N
KEY_register_keyinfo( 50, 109, 77) ; m and M
KEY_register_keyinfo( 51, 44, 60) ; , and <
KEY_register_keyinfo( 52, 46, 62) ; . and >
KEY_register_keyinfo( 53, 47, 63) ; / and ?
KEY_register_keyinfo( 15, 9, 9) ; tab
KEY_register_keyinfo( 57, 32, 32) ; space
KEY_register_keyinfo( 28, 13, 13) ; enter
KEY_register_keyinfo(181, 47, 47) ; numpad /
KEY_register_keyinfo( 55, 42, 42) ; numpad *
KEY_register_keyinfo( 74, 45, 45) ; numpad -
KEY_register_keyinfo( 78, 43, 43) ; numpad +
KEY_register_keyinfo(156, 13, 13) ; numpad enter
KEY_register_keyinfo( 79, 49, 49) ; numpad 1
KEY_register_keyinfo( 80, 50, 50) ; numpad 2
KEY_register_keyinfo( 81, 51, 51) ; numpad 3
KEY_register_keyinfo( 75, 52, 52) ; numpad 4
KEY_register_keyinfo( 76, 53, 53) ; numpad 5
KEY_register_keyinfo( 77, 54, 54) ; numpad 6
KEY_register_keyinfo( 71, 55, 55) ; numpad 7
KEY_register_keyinfo( 72, 56, 56) ; numpad 8
KEY_register_keyinfo( 73, 57, 57) ; numpad 9
KEY_register_keyinfo( 82, 48, 48) ; numpad 0
KEY_register_keyinfo( 83, 46, 46) ; numpad .
End Function
;--------------------------------------------------------
Function KEY_register_manipulation_keys()
;--------------------------------------------------------
KEY_register_keyinfo(199, 1, 1) ; home
KEY_register_keyinfo(207, 2, 2) ; end
KEY_register_keyinfo( 14, 8, 8) ; backspace
KEY_register_keyinfo(211, 4, 4) ; delete
KEY_register_keyinfo(203, 31, 31) ; left
KEY_register_keyinfo(205, 30, 30) ; right
End Function
;--------------------------------------------------------
Function KEY_GetKey()
;--------------------------------------------------------
Local trigger_keystroke = False
; is the user still pressing the previous key?
If KEY_Global\depressed_key <> Null Then
If KeyDown(KEY_Global\depressed_key\scancode) Then
; user is still pressing the key, so generate repeating keystrokes
If KEY_Global\repeat_timer < MilliSecs() Then
KEY_Global\repeat_timer = MilliSecs() + KEY_Global\repeat_subsequent_delay
trigger_keystroke = True
EndIf
Else
; user has stopped pressing the key
KEY_Global\depressed_key = Null
EndIf
EndIf
; has the user pressed a new key? (check the key positions for each recognized scancode)
For key.KEY_info = Each KEY_info
If KeyHit(key\scancode) Then Exit
Next
; if we found a recognized key, remember it's being pressed, and return it
If key <> Null Then
KEY_Global\depressed_key = key
KEY_Global\repeat_timer = MilliSecs() + KEY_Global\repeat_initial_delay
trigger_keystroke = True
EndIf
If trigger_keystroke Then
; the ascii code we want to return often depends on if shift is being pressed
If KeyDown(42) Or KeyDown(54) Then
Return KEY_Global\depressed_key\ascii_shift
Else
Return KEY_Global\depressed_key\ascii_plain
EndIf
EndIf
Return 0
End Function
;--------------------------------------------------------
; EXAMPLE
;--------------------------------------------------------
;
;SetBuffer = BackBuffer()
;
;KEY_register_printable_keys()
;
;input_string$ = ""
;While Not KeyHit(1)
; char = KEY_GetKey()
; If char > 0 Then input_string$ = input_string$ + Chr$(char)
;
; Cls
; Locate 1, 1
; Print "Press and hold keys to see repeating effect"
; Print input_string$ + cursor$
; Flip
;Wend |
Comments
| ||
| Superb piece of work - worked perfectly for me! Busily writing an interactive character-by-character peer-to-peer chat program and this was just what I needed - able to plug it straight in! Many thanks. |
Code Archives Forum