gpt4 book ai didi

vba - 将 MapVirtualKeyA 与 Shift 和 Ctrl Alt 一起使用

转载 作者:行者123 更新时间:2023-12-04 14:13:14 32 4
gpt4 key购买 nike

我找到了 this page对于将给定键码转换为相应字符的函数,具体取决于系统语言和键盘布局。我测试了它(在 PowerPoint 中使用 VBA)并且它可以工作,除了我不知道如何告诉函数 ShiftCtrl + Alt 正在被按下,因此函数应该返回不同的结果。比方说:键码 51 对应数字 3,当我将它传递给函数时,它返回 3。但是如果用户按下 Shift 键呢?它应该返回 #(或不同的字符,取决于键盘布局等)

所以,我知道如何检查 ShiftCtrl + Alt 是否被按下,但我不知道如何告诉函数按键正在受到压力。

我将以下代码放在一个模块中:

Public Declare PtrSafe Function MapVirtualKeyA Lib "user32" (ByVal uCode As Long, ByVal uMapType As Long) As Integer

然后我在幻灯片的代码中输入:

Sub test()

MsgBox Chr(MapVirtualKeyA(vbKey3, 2)) ' always returns 3, even when pressing shift or ctrl + alt

End Sub

我想知道我必须在我的代码中更改什么,以便函数知道正在按下 ShiftCtrl + Alt

提前致谢。

最佳答案

要理解您问题的答案,我们需要先了解一下键盘输入的工作原理。

Microsoft 对此有一个完整的部分:

当在 keyboard 上按下一个键时, 一个 scan code生成。扫描码取决于设备。

下一步:

The keyboard device driver receives scan codes from the keyboard

并将它们变成虚拟键:

a device-independent value defined by the system that identifies the purpose of a key.

虚拟键表示键盘上的键,而不是它们可以表示的字符。因此,例如 3 是一个虚拟键,但它是移位值(在我的例子中是 £),不是,并且取决于所使用的键盘。

这些存储在设备相关的 KeyboardLayout 中。 MapVirualKey 等基本函数调用使用默认键盘布局(即您现在使用的键盘布局)。如果你想使用不同的布局,你可以通过调用获取列表:

GetKeyboardLayoutList

因此一个虚拟键和任何修饰符被发送到键盘布局,这将返回适当的字符,然后将其呈现到屏幕等...

因此您的问题变成了“我们如何找到 myKey + shift 的 Unicode/ASCII 值?”。没有任何特别简单的答案,例如在我的计算机上“shift 3 (£)”的 ASCII 值为 163,但“shift 4 ($)”的 ASCII 值为 36!

这些示例使用 Excel,而不是 Powerpoint。

让我们看看MapVirtualKey`第一的。我没有使用一般的键盘布局。

在模块中,添加以下声明:

' https://learn.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://learn.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'。

等待处理器 catch ......,我们有“£”的 ASCII 值!

关于vba - 将 MapVirtualKeyA 与 Shift 和 Ctrl Alt 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62662843/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com