将 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 结合使用 的相关文章

  • 如何使用 xlwings 从 Python 调用 Excel 宏?

    我读过API docs http docs xlwings org api html对于 xlwings 并在解释器中使用 Workbook 和 Sheet 对象 但我不知道如何从 Python 调用宏 如何使用 xlwings 从 Pyt
  • 如何从 500 个 .xls Excel 文件中的单元格中获取数据?

    我想问你如何从许多Excel中的几个确定的 并且总是相同的 单元格中获取数据 xls文件 即我有一个清单 xls文件位于一个文件夹中 每个文件内部都有相同的表 但具有不同的值 我想从以下位置获取数据A1 C2 E3从文件夹中的所有文件中提取
  • VBA - 填充自定义功能区下拉列表/列表框

    我无法填充下拉列表 列表框 原始代码来自 https exceloffthegrid com inserting a dynamic drop down in ribbon https exceloffthegrid com inserti
  • 使用VBA复制垂直列并沿对角线粘贴

    我有一列数据 我们称之为 A 列 其中有 35 行数据 如何在此列上循环 然后将每个数据点粘贴到另一张工作表中 同时为每个循环循环增加列和行 换句话说 我寻求对角粘贴在第二张纸中 有没有一种简单的方法可以在 VBA 中执行此类操作 不要循环
  • 运行代码(而不是查询)时如何在状态栏上显示进度

    我已经发布了有关在 MS Access 2010 中运行查询时更新状态栏的问题 请参阅在 MS Access 中运行一系列查询时如何在状态栏上显示进度 https stackoverflow com questions 27765376 h
  • 使用 VBA 的下拉菜单

    我需要使用 VBA 从下拉菜单中选择特定选项 我怎样才能做到这一点 链接到我们试图从中提取的网页 IE document getElementsByName down count click 我尝试过的代码 Full Module Priv
  • 在 Excel 表格中选择多列的代码

    我是 Excel VBA 新手 我需要修改我的代码 以便我能够进一步进行 我想在 Excel 表格中选择多个表格列 这是我的代码 Dim ws As Worksheet Dim tbl As ListObject Set ws Sheets
  • 如何在VBA编辑器中跳转到行号?

    我在 Office 2010 中使用 VBA 在顶部 有一个带有行号和列号的框 例如 Ln 1480 Col 17 有没有办法在代码编辑中 而不是在执行中 直接跳转到另一个行号 就像我使用的那样Ctrl G在记事本中 这个MSDN答案 ht
  • VBA Shell 并等待退出代码

    我正在打包一个办公应用程序 VBA 它调用 C 控制台应用程序来执行应用程序 大型模拟程序 的一些繁重工作 我希望能够让 VBA 应用程序等待控制台应用程序完成并从控制台应用程序检索退出代码 我已经能够做到前者 但尚未能够从应用程序中检索退
  • 我可以获取VBA代码中的注释文本吗

    可以说我有以下内容 Public Sub Information TEST End Sub 有没有办法得到 TEST 结果 不知何故通过VBA 例如 在 PHP 中 有一个获取注释的好方法 这里有什么想法吗 编辑 应该有办法 因为像 MZ
  • 获取当前 VBA 函数的名称

    对于错误处理代码 我想获取发生错误的当前 VBA 函数 或子函数 的名称 有谁知道如何做到这一点 编辑 谢谢大家 我曾希望存在一个未记录的技巧来自行确定函数 但这显然不存在 我想我会保留当前的代码 Option Compare Databa
  • SQL Excel VBA 运行时错误 3709 无效连接

    这是我的第一个问题 欢迎提出建设性的批评 我正在尝试从 Excel VBA 查询 Access 数据库并将返回信息放入 Excel 范围中 我收到此错误 错误消息 运行时错误 3709 连接无法用于 执行此操作 在此情况下它已关闭或无效 语
  • 在 VBA 中捕获 shell 命令的输出值?

    发现这个功能http www cpearson com excel ShellAndWait aspx http www cpearson com excel ShellAndWait aspx 但我还需要捕获 shell 的输出 有什么代
  • 数据透视表错误 |无效的调用或过程

    我需要一些帮助来解决这个问题 我正在尝试创建一个数据透视表 从第一季度开始 在同一张表中包含一系列数据 第一个 if 语句在那里是因为最后一列并不总是包含标题 所以我将其包含在那里 我希望范围是动态的 因为所制作的表格的大小将根据工作表中数
  • 使用图表时避免使用“激活”和“选择”(Excel)

    我知道使用Activate and Select在 Excel 中 VBA 不是最佳实践 我看过有关如何在处理范围时避免它们的参考资料 例如 LINK https stackoverflow com questions 10714251 e
  • 使用宏从 Excel 电子表格中删除任何非指定字符

    我正在尝试通过删除任何非标准字符来清理 Excel 中的 CSV 文件 我唯一关心保留的字符是 A Z 0 9 和一些标准标点符号 任何其他字符 我想删除 当它找到包含我未指定的任何字符的单元格时 我已经得到了以下宏来删除整行 但我不确定如
  • 删除 VBA 按钮集合

    我正在使用以下脚本在 Excel 中生成按钮 范围正是我希望放置它的位置 Sub CreateAddButton rng As Range Dim btn As Button With Worksheets User Set btn But
  • 使用 Excel VBA 循环工作簿文件夹并将所有工作表导出为制表符分隔文本

    我拼凑了一个 Excel VBA 脚本 该脚本将打开的工作簿中的所有工作表写入单独的制表符分隔文件 这仍然是 宏 吗 我正在 Excel 真空中学习这一点 它一次只处理一本工作簿 效果很好 这里是 Sub exportSheetsToTex
  • 字符串在换行符处拆分

    我在 MS Access 表单上有一个文本框 用户将从 Excel 电子表格中复制一列数字到其中 我需要获取此输入并将其用作参数来构建查询 我的代码看起来像这样 Dim data as variant Dim input as String
  • 从 VBA 访问串行端口的最佳方法是什么?

    从 VBA 访问串行端口的最佳方法是什么 我需要我们的一些销售代表能够通过 PowerPoint 中的操作按钮通过串行端口发送简单的字符串 我不常用 VBA 尤其是像这样的事情 通常我会把它变成某种应用程序 但实际上我认为这个想法并没有那么

随机推荐

  • 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用于将给定的键码转换为相应的字符的函数 具体取决于系统语