将 MapVirtualKeyA 与 Shift 和 Ctrl Alt 结合使用

2024-01-18

我已经发现这一页 https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mapvirtualkeya用于将给定的键码转换为相应的字符的函数,具体取决于系统语言和键盘布局。我测试了它(在 PowerPoint 中使用 VBA)并且它有效,但我不知道如何告诉该函数Shift or Ctrl + Alt被按下,因此该函数应该返回不同的结果。举例来说:键码 51 对应于数字 3,当我将其传递给函数时,它返回3。但是如果用户按下 Shift 键怎么办?它应该返回#(或不同的字符,具体取决于键盘布局等)

所以,我知道如何检查Shift or Ctrl + 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

我想知道我必须在代码中更改什么以便该函数知道Shift or Ctrl + Alt正在被压制。

提前致谢。


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

微软有一个完整的章节来讨论这个问题:

  • https://learn.microsoft.com/en-gb/windows/win32/inputdev/about-keyboard-input https://learn.microsoft.com/en-gb/windows/win32/inputdev/about-keyboard-input

当按下某个键时keyboard https://en.wikipedia.org/wiki/Computer_keyboard#Control_processor, a 扫码 https://en.wikipedia.org/wiki/Scancode被生成。扫描码取决于设备。

Next:

键盘设备驱动程序接收来自键盘的扫描码

并将它们变成虚拟按键:

由系统定义的与设备无关的值,用于标识密钥的用途。

虚拟键代表键盘上的按键,而不是它们可以代表什么字符。所以,例如3是一个虚拟键,但它的值被移动了(£就我而言),不是,并且取决于所使用的键盘。

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

GetKeyboardLayoutList https://learn.microsoft.com/en-gb/windows/win32/api/winuser/nf-winuser-getkeyboardlayoutlist

因此,虚拟键和任何修饰符都会发送到键盘布局,并返回适当的字符,然后将其渲染到屏幕上,等等......

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

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

让我们看看映射虚拟密钥` https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mapvirtualkeya第一的。我没有使用过通用的键盘布局。

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

' 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”应该返回什么没有多大用处。

我们可以从中检索“shift”状态£,通过使用VkKeyScanAPI函数。

在模块中声明该函数:

' 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)

这提供了更多信息,但仍然没有给我们答案。

这里有两种解决方案,两者几乎相同:

  • 发送输入 https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput
  • SendKeys https://learn.microsoft.com/en-us/office/vba/Language/Reference/user-interface-help/sendkeys-statement

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将光标放在我们想要的位置。

+用于模拟“移位”,并且~模拟“输入”。

等待处理器赶上......,我们就得到了“£”的 ASCII 值!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 MapVirtualKeyA 与 Shift 和 Ctrl Alt 结合使用 的相关文章

随机推荐

  • R 中的 Collat​​z 猜想

    我仍然主要向我自己 和我的学生 教授一些 R 下面是 Collat z 序列在 R 中的实现 f lt function n construct the entire Collatz path starting from n if n 1
  • 寻找 C/C++ 中的 GD 教程 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我看到很多 PHP 的 GD 教程 尽管 GD 是用 C 编写的 而不是 PHP 你能推荐一些好的 C 语言 GD 教程吗 我在谷歌上搜索
  • ASP.Net MVC:将 JSON 发送到控制器

    在 ASP Net MVC 中向我的控制器发布帖子时 我希望能够发送 JSON 而不是标准查询字符串 我的前端工作正常 构建然后提交我的 JSON 对象 问题出在控制器端 MVC 框架附带的默认 ModelBinder 不支持此功能 我已经
  • 如何在页面的 Javascript 执行后加载内容脚本?

    我的扩展应该仅在其注入的页面已完全加载之后加载内容脚本 searchTopic js 是的 我已在扩展清单中将 run at 设置为 document end 但实际上它是在之前加载的所有 DOM 对象都已创建 关键的对象是通过页面中的一些
  • 房间数据库迁移fallbackToDestructiveMigration()不起作用

    我正在使用 Room 并在资产文件夹中预填充数据库 对于应用程序更新 我想通过添加新列并用新数据预填充此列来更改此数据库 数据库从版本 1 自动迁移到版本 2 添加了一个表 从版本 2 到版本 3 我现在想通过在资产文件夹中提供不同的 da
  • 如何在 Python 中生成可重现(带有种子)的随机 UUID

    The uuid4 https docs python org 2 library uuid html uuid uuid4Python模块的功能uuid生成一个随机的 UUID 并且似乎每次都会生成不同的 UUID In 1 import
  • 如何对 CI 管道中使用不属于 git 远程的模型文件的函数进行单元测试?

    我正在开发机器学习存储库 需要相当大的经过训练的模型文件才能运行 这些文件不是 git Remote 的一部分 但由 DVC 跟踪并保存在单独的远程存储中 当我尝试在 CI 管道中为需要这些模型文件进行预测的函数运行单元测试时 我遇到了问题
  • SCons配置文件和默认值

    我有一个使用 SCons 构建的项目 以及 MinGW gcc 具体取决于平台 这个项目依赖于其他几个库 我们称它们为libfoo and libbar 可以为不同的用户安装在不同的地方 目前 我的SConstruct文件嵌入了这些库的硬编
  • 如何生成包含所有问题的报告?

    我有一个在 AWB 中打开的 Fortify FPR 扫描文件 我想生成一份报告 其中包含发现问题的所有实例 当我生成报告时 它会生成按类型及其计数列出问题的报告 并且在类型下方我还会获得以下名称和代码片段some发现问题的文件 我想生成一
  • 在 iOS 9 上使用 NavigationController 自定义推送动画的过渡

    我在嵌入的视图控制器之间有一个自定义的推送转换UINavigationController当使用 iOS 7 8 构建时工作正常 但当针对 iOS 9 SDK 构建时会出现错误的布局 void animateTransition id
  • 从情节提要中的模态视图推送视图控制器

    我正在使用故事板并有一个以模态方式呈现的屏幕 然后我需要从中推送其他视图控制器 以便我可以为模态视图选择项目 类似于在 iPhone 日历应用程序上添加条目 所以我将从 导航控制器 gt VC gt 模态视图控制器 gt 这里我想推送一个V
  • 如何在 Material UI 中对齐水平图标和文本

    我是 Material UI 的新手 现在我的图标和文本未对齐 我想要的结果 我的代码是 div div
  • 河内塔 - 如何在每次递归时不跳过钉子

    我的任务是使用递归求解任意数字的河内塔 我用 C 编写了代码 Rules 无法将较大的磁盘堆叠在较小的磁盘之上 一次无法移动多个磁盘 3 一次只移动一个圆盘 不要回到起点或离开终点 如下 开始 gt peg1 peg2 peg3 gt EN
  • 定义 Laravel 表单字段的默认值

    要预填充表单字段 我们可以将 值 添加到 create blade php 中的表单字段 Form text title Some default title 有没有办法在其他地方 也许在模型或控制器中 完成该任务 我希望在创建和编辑视图中
  • 使用反射和列表的 C# 动态转换

    从昨天开始我就在解决一个问题 但我还没明白 我有一个包含许多方法的类 并在运行时决定必须调用哪个方法 每个方法都会返回一个列表 其中包含来自我的业务对象的元素 我的班级是这样的 public class ReflectiveClass pu
  • 使用 FBSDKCoreKit.framework 在 Xcode10 中发现意外的 Mach-O 标头代码:0x72613c21

    我有一个使用最新版本的 FacebookSDK 和 Xcode 10 的项目 该项目在设备中运行正常 但是在提交到 App Store 时 在验证过程中出现以下错误 发现意外的 Mach O 标头代码 0x72613c21 日志显示 201
  • Win32API 结构中 cbSize 成员的用途是什么

    我经常遇到一些 Win32API 结构 但不限于此 的定义 它们具有cbSize成员 如下例所示 typedef struct TEST int cbSize other members follow TEST PTEST 然后我们像这样使
  • 通过 Html.BeginForm 提交激活加载动画

    我想在用户单击提交按钮时显示加载动画 简单的 gif 就可以完成工作 这是我的代码 using Html BeginForm SData Crawl p Enter Starting URL p
  • 如何从 glm 对象获取 Z 统计值?

    如何获取 Z 统计值作为向量glm目的 例如 我有 fit lt glm y 0 x binomial 如何访问该专栏Pr gt z 同样的方式我得到系数的估计fit coef 我相信 coef summary fit Pr gt z 会给
  • 将 MapVirtualKeyA 与 Shift 和 Ctrl Alt 结合使用

    我已经发现这一页 https learn microsoft com en us windows win32 api winuser nf winuser mapvirtualkeya用于将给定的键码转换为相应的字符的函数 具体取决于系统语