Convert a Character Code to a string describing the Keyboard Keys which must be pressed
Different keyboard layouts use different virtual key codes and shift combinations to represent character codes. This tip demonstrates how to convert a key code into the equivalent virtual key code and shift state, as well as how to provide the name of a virtual key on the keyboard.
There are two stages in converting a character into the keyboard equivalent. The first stage is to obtain the Keyboard Scan Code for the character, using the API call VkKeyScan. This provides the key's virtual key code and the shift state. Once that has been done, the virtual key code can be converted to the name of the key using the MapVirtualKey and GetKeyNameText functions.
Converting a Character to the Virtual Key and Shift State
The code below shows how this is achieved. First, the GetVersion function is called to determine whether the system is NT and has Unicode support or not. This is indicated by the high-bit of the return value being set. Then a suitable value is prepared for the VkKeyScan call. For Unicode systems this is an Integer value whereas ANSI systems use Byte values. Then the result of the call is an integer where the low-byte is the virtual key code and the high-byte is the shift state, made up from a ORed combination of the constants in VB's ShiftConstant values:
Private Declare Function GetVersion Lib "kernel32" () As Long Private Declare Function VkKeyScan Lib "user32" Alias "VkKeyScanA" ( _ ByVal cChar As Byte) As Integer Private Declare Function VkKeyScanW Lib "user32" ( _ ByVal cChar As Integer) As Integer ... Dim bNt As Boolean Dim iKeyCode As Integer Dim b() As Byte Dim iKey as integer Dim vKey as KeyCodeConstants Dim iShift As ShiftConstants ' Determine if we have Unicode support or not: bNt = ((GetVersion() And &H80000000) = 0) ' Get the keyboard scan code for the character: If (bNt) Then b = sChar CopyMemory iKey, b(0), 2 iKeyCode = VkKeyScanW(iKey) Else b = StrConv(sChar, vbFromUnicode) iKeyCode = VkKeyScan(b(0)) End If ' Split into shift and key portions: iShift = (iKeyCode And &HFF00&) \ &H100& vKey = iKeyCode And &HFF&
Converting the Virtual Key Code to a Keyboard Name
To convert the key code, first the Unicode or ANSI version of MapVirtualKey is called. This returns a scan code which can be used to obtain the name of the key from the GetKeyNameText function. This function expects the scan code in a long value shifted to the high word and a pointer to an buffer which will hold the keyboard text name. In the Unicode world this needs to be a byte array with two bytes for each character in the buffer whereas in ANSI it is a pre-allocated VB string. The code to achieve this is shown below:
Dim lScanCode As Long Dim sBuf As String Dim lSize As Long Dim b() As Byte ' Translate the virtual-key code into a scan code. If (bNt) Then lScanCode = MapVirtualKeyW(vKey, 0) Else lScanCode = MapVirtualKey(vKey, 0) End If ' GetKeyNameText retrieves the name of a key (the scan code ' must be in bits 16-23): lScanCode = lScanCode * &H10000 If (bNt) Then ReDim b(0 To 512) As Byte lSize = GetKeyNameTextW(lScanCode, VarPtr(b(0)), 256) If (lSize > 0) Then sBuf = b sKeyName = Left$(sBuf, lSize) End If Else sBuf = Space$(256) lSize = GetKeyNameText(lScanCode, sBuf, 256) sKeyName & Left$(sBuf, lSize) End If
The sample application in the download wraps this function into a simple function within a module called GetKeyboardString. This takes a character as a VB string and returns a string with the keystroke, as well as populating two optional parameters vKey and iShift with the virtual key and shift flags.