I have found this page for a function that converts a given keycode in to the corresponding charcater, depending on the system language and keyboard layout. I tested it (in PowerPoint using VBA) and it works, except I don't know how to tell the function that Shift
or Ctrl + Alt
are being pressed and therefore the function should then return a different result. Say for instance: The keycode 51 corresponds to the number 3, when I pass it to the function, it returns 3
. But what if the user is pressing the Shift key? It should return #
(or a different character, depending on the keyboard layout, etc.)
So, I know how to check if Shift
or Ctrl + Alt
are being pressed, but what I don't know is how to tell the function that the keys are being pressed.
I put the following code in a module:
Public Declare PtrSafe Function MapVirtualKeyA Lib "user32" (ByVal uCode As Long, ByVal uMapType As Long) As Integer
And then in the slide's code I put:
Sub test()
MsgBox Chr(MapVirtualKeyA(vbKey3, 2)) ' always returns 3, even when pressing shift or ctrl + alt
End Sub
I want to know what I have to change in my code so that function knows that Shift
or Ctrl + Alt
are being pressed.
Thanks in advance.
You could use ToAscii API.
Option Explicit
Private Declare PtrSafe Function ToAscii Lib "user32" (ByVal uVirtKey As Long, ByVal uScanCode As Long, lpbKeyState As Byte, lpChar As LongPtr, ByVal uFlags As Long) As Long
Private Declare PtrSafe Function MapVirtualKeyA Lib "user32" (ByVal uCode As Long, ByVal uMapType As Long) As Long
Sub Test()
Debug.Print GetCharacterFromVK(uVirtKey:=vbKey3, shiftDown:=True)
End Sub
Function GetCharacterFromVK(uVirtKey As Long _
, Optional shiftDown As Boolean = False _
, Optional ctrlDown As Boolean = False _
, Optional altDown As Boolean = False _
) As String
'https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
Const VK_SHIFT = &H10 'SHIFT key
Const VK_CONTROL = &H11 'CTRL key
Const VK_MENU = &H12 'ALT key
'
Dim keyState(0 To 255) As Byte
Dim buffer As String: buffer = Space$(2)
'
'Set Key States by setting the high-order bit of the byte
If shiftDown Then keyState(VK_SHIFT) = &H80
If ctrlDown Then keyState(VK_CONTROL) = &H80
If altDown Then keyState(VK_MENU) = &H80
'
'Populate buffer
Select Case ToAscii(uVirtKey, MapVirtualKeyA(uVirtKey, 0), keyState(0), ByVal StrPtr(buffer), 0)
Case 0
'The specified virtual key has no translation for the current state of the keyboard
GetCharacterFromVK = vbNullString
Case 1
'One character was copied to the buffer
GetCharacterFromVK = Left$(buffer, 1)
Case 2
'Two characters were copied to the buffer
GetCharacterFromVK = buffer
End Select
End Function