要了解这个问题的答案,我们需要先了解键盘输入的工作原理。
微软对此有一个完整的部分:
当在keyboard 上按下一个键时,会生成一个scan code。扫描码取决于设备。
下一步:
键盘设备驱动程序从键盘接收扫描码
并将它们变成虚拟键:
由系统定义的独立于设备的值,用于标识密钥的用途。
虚拟键代表键盘上的键,而不是它们可以代表什么字符。因此,例如 3 是一个虚拟键,但它是移位值(在我的例子中是 £),不是,并且取决于使用的键盘。
这些存储在设备相关的键盘布局中。 MapVirualKey 等基本函数调用使用默认键盘布局(即您现在使用的键盘布局)。如果你想使用不同的布局,你可以通过调用得到一个列表:
GetKeyboardLayoutList
因此,虚拟键和任何修饰符都会发送到键盘布局,这会返回适当的字符,然后将其呈现到屏幕等...
所以您的问题变成了“我们如何找到 myKey + shift 的 Unicode/ASCII 值?”。没有任何特别简单的答案,例如在我的计算机上 'shift 3 (£)' 的 ASCII 值为 163,但 'shift 4 ($)' 的 ASCII 值为 36!
这些示例使用 Excel,而不是 Powerpoint。
让我们先看看MapVirtualKey`。我没有使用一般的键盘布局。
在模块中,添加以下声明:
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mapvirtualkeya
Public Declare PtrSafe Function MapVirtualKeyA Lib "user32" ( _
ByVal uCode As Long, _
ByVal uMapType As Long) As Integer
并将以下子程序添加到 Button1:
Sub Button1_Click()
Cells.Clear
' MapVirtualKeyA
Cells(1, 1) = "MapVirtualKeyA"
Cells(1, 1).Font.Bold = 1
char = "3"
Cells(2, 1) = "char: " & char
Cells(2, 2) = MapVirtualKeyA(Asc(char), 2)
Cells(2, 3) = Chr(MapVirtualKeyA(Asc(char), 2))
char = "£"
Cells(3, 1) = "char: " & char
Cells(3, 2) = MapVirtualKeyA(Asc(char), 2)
Cells(3, 3) = Chr(MapVirtualKeyA(Asc(char), 2)) ' doesn't exist
第一个调用正常,第二个调用不将£ 识别为虚拟键(不是),因此返回0。
所以这对于确定 'shift 3' 应该返回什么没有多大用处。
我们可以使用VkKeyScan API 函数从£ 检索“shift”状态。
在模块中声明函数:
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-vkkeyscana
Public Declare Function VkKeyScan Lib "user32" Alias "VkKeyScanA" ( _
ByVal cChar As Byte) As Integer
并将此代码添加到按钮:
'VkKeyScan
Cells(5, 1) = "VkKeyScan"
Cells(5, 1).Font.Bold = 1
char = "3"
keyScan = VkKeyScan(Asc(char))
shift = keyScan And &H100
ctrl = keyScan And &H200
vkKey = keyScan And &HFF
Cells(6, 1) = "char: " & char
Cells(6, 2) = "shift: " & shift
Cells(6, 3) = "ctrl: " & ctrl
Cells(6, 4) = keyScan
Cells(6, 5) = ChrW(keyScan)
Cells(6, 6) = vkKey
Cells(6, 7) = Chr(vkKey)
char = "£"
keyScan = VkKeyScan(Asc(char))
shift = keyScan And &H100
ctrl = keyScan And &H200
vkKey = keyScan And &HFF
Cells(7, 1) = "char: " & char
Cells(7, 2) = "shift: " & shift
Cells(7, 3) = "ctrl: " & ctrl
Cells(7, 4) = keyScan
Cells(7, 5) = ChrW(keyScan) ' wrong character
Cells(7, 6) = vkKey
Cells(7, 7) = Chr(vkKey)
这提供了更多信息,但仍然没有给我们答案。
这里有两种解决方案,两者几乎相同:
SendInput 是官方的 Win32API 做事方式,但涉及相当长的代码,并且被 VBA 的SendKeys 函数整齐地包裹起来。
SendKeys 将文本输出发送到当前活动的光标。
Cells(10, 1).Select
SendKeys ("3+3~")
While Cells(10, 1) = ""
DoEvents
Wend
Cells(10, 2) = Asc(Mid(Cells(10, 1), 1, 1))
Cells(10, 3) = Asc(Mid(Cells(10, 1), 2, 1))
End Sub
Cells(10, 1).Select 将光标放在我们想要的位置。
+用于模拟'shift',~模拟'enter'。
等待处理器赶上..,我们有 '£' 的 ASCII 值!