Get key names from virtual keys

Share your advanced PureBasic knowledge/code with the community.
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Get key names from virtual keys

Post by luis »

Win, PB 520

This code show a somewhat domesticated use of MapVirtualKey() and GetKeyNameText() to get the descriptive name for a key starting from its virtual key code.

This can be useful for mapping keys in games and show to the user the name of the key pressed, for example.

virtual key codes are sometimes dependent on the layout, for example all the #VK_OEM_[NUMBER]

http://msdn.microsoft.com/en-us/library ... 85%29.aspx

So when the user press that key it's in the same position on a USA or ITA keyboard, but the character printed on it it's different. If you want to show that on the screen starting from its virtual code this mapping approach can help.

In this example I want to always show the English naming of the keys, if you want to show something different change temporary the input locale (as shown in the code) and if you want to use the current keyboard layout used by the OS just comment out the Load/ActivateKeyboardLayout() stuff.

Code: Select all

Macro MAKELANGID (primary, sublang)
  (((sublang)<<10)|(primary))
EndMacro

#KLF_SETFORPROCESS = 256

Buffer$ = RSet("",128," ")
iDataSize = Len(Buffer$)

DoNotCareFlag = 0

; I want always english... if you want another layout use something like these :

;hTempLocale$ = RSet(Hex(MAKELANGID(#LANG_FRENCH, #SUBLANG_FRENCH)),8,"0") 
;hTempLocale$ = RSet(Hex(MAKELANGID(#LANG_ITALIAN, #SUBLANG_ITALIAN)),8,"0")

hTempLocale$ = RSet(Hex(MAKELANGID(#LANG_ENGLISH, #SUBLANG_ENGLISH_US)),8,"0")
hTempLayout = LoadKeyboardLayout_(hTempLocale$, #KLF_ACTIVATE)
hPrevInputLocale = ActivateKeyboardLayout_(hTempLayout, #KLF_SETFORPROCESS)

Dim KeyName$(256)
 
For i = 0 To 255
    ScanCode = MapVirtualKey_(i,0) ; virtual key code to scan code

    Select i        
        Case $07, $0E, $0F, $16, $1A, $3A To $40 ; undefined
            Continue
        Case $0A, $0B, $5E, $B8, $B9, $C1 To $D7, $E0 ; reserved
            Continue
        Case $88 To $8F, $97 To $9F, $D8 To $DA, $E8 ; unassigned
            Continue
        Case $A6 To $AC ; browser keys            
            Continue
        Case $AD To $B7 ; multimedia keys
            Continue
        Case #VK_PAUSE ; missing (bug ?)
            KeyName$(i) = "Pause"
            Continue
        Case #VK_CLEAR ; shift + keypad 5 (what the hell is that ?)
            KeyName$(i) = "Clear" 
            Continue
            
        ; extended keyboard    
        Case #VK_CANCEL, #VK_NUMLOCK,
             #VK_PRIOR, #VK_NEXT, #VK_END, #VK_HOME, #VK_INSERT, #VK_DELETE, 
             #VK_LEFT, #VK_RIGHT, #VK_UP, #VK_DOWN, 
             #VK_LWIN, #VK_RWIN, #VK_APPS, #VK_RCONTROL, #VK_RMENU             
            ExtKeyFlag = 1           
            
        ; normal keyboard    
        Default
            ExtKeyFlag = 0            
    EndSelect
        
    If ScanCode And GetKeyNameText_((ScanCode << 16) | (ExtKeyFlag << 24) | (DoNotCareFlag << 25),  @Buffer$, iDataSize)
        ; description provided by the keyboard driver
        KeyName$(i) = Buffer$        
    EndIf                        
Next 

ActivateKeyboardLayout_(hPrevInputLocale, #KLF_SETFORPROCESS)
UnloadKeyboardLayout_(hTempLayout)

For i = 0 To 255
    If Len(KeyName$(i)) 
        Debug "0x" + RSet(Hex(i), 2, "0") + " = " + KeyName$(i) 
    EndIf
Next

Code: Select all

0x03 = Break
0x08 = Backspace
0x09 = Tab
0x0C = Clear
0x0D = Enter
0x10 = Shift
0x11 = Ctrl
0x12 = Alt
0x13 = Pause
0x14 = Caps Lock
0x1B = Esc
0x20 = Space
0x21 = Page Up
0x22 = Page Down
0x23 = End
0x24 = Home
0x25 = Left
0x26 = Up
0x27 = Right
0x28 = Down
0x2C = Sys Req
0x2D = Insert
0x2E = Delete
0x30 = 0
0x31 = 1
0x32 = 2
0x33 = 3
0x34 = 4
0x35 = 5
0x36 = 6
0x37 = 7
0x38 = 8
0x39 = 9
0x41 = A
0x42 = B
0x43 = C
0x44 = D
0x45 = E
0x46 = F
0x47 = G
0x48 = H
0x49 = I
0x4A = J
0x4B = K
0x4C = L
0x4D = M
0x4E = N
0x4F = O
0x50 = P
0x51 = Q
0x52 = R
0x53 = S
0x54 = T
0x55 = U
0x56 = V
0x57 = W
0x58 = X
0x59 = Y
0x5A = Z
0x5B = Left Windows
0x5C = Right Windows
0x5D = Application
0x60 = Num 0
0x61 = Num 1
0x62 = Num 2
0x63 = Num 3
0x64 = Num 4
0x65 = Num 5
0x66 = Num 6
0x67 = Num 7
0x68 = Num 8
0x69 = Num 9
0x6A = Num *
0x6B = Num +
0x6D = Num -
0x6E = Num Del
0x6F = /
0x70 = F1
0x71 = F2
0x72 = F3
0x73 = F4
0x74 = F5
0x75 = F6
0x76 = F7
0x77 = F8
0x78 = F9
0x79 = F10
0x7A = F11
0x7B = F12
0x90 = Num Lock
0x91 = Scroll Lock
0xA0 = Shift
0xA1 = Right Shift
0xA2 = Ctrl
0xA3 = Right Ctrl
0xA4 = Alt
0xA5 = Right Alt
0xBA = ;
0xBB = =
0xBC = ,
0xBD = -
0xBE = .
0xBF = /
0xC0 = `
0xDB = [
0xDC = \
0xDD = ]
0xDE = '
0xE2 = \

By the way, I would like to see the equivalent of this code for OSX, and maybe Linux too. :wink:
"Have you tried turning it off and on again ?"
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Get key names from virtual keys

Post by Kwai chang caine »

Coooool !!! and very useful ... :shock:
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply