【问题标题】:Simulating number-sign (#) keystroke in C#在 C# 中模拟数字符号 (#) 击键
【发布时间】:2014-06-22 12:10:45
【问题描述】:

我正在尝试在 user32.dll 中使用 SendInput 准确地键入井号(数字符号、井号、八角符号,随便你怎么称呼它)。

这些是我看到的可能选项:

  1. 通过模拟 SHIFT+3(SHFT_DN、3_DN、3_UP、SHFT_UP)键入数字符号。我唯一担心的是美国布局的键盘。配置了非美国布局的系统是否有可能输出错误的键?

  2. 我的另一个选择是通过模拟按键按 ascii 码插入字符:ALT+035(ALT_DN、NUMPAD0_DN、NUMPAD0_UP、NUMPAD3_DN、NUMPAD3_UP、NUMPAD5_DN、NUMPAD5_UP、ALT_UP )。这种方法有什么重大缺陷吗?所有区域是否共享相同的 ASCII 代码,Windows 是否在所有区域都提供此 ALT+### 功能?这也将为单个简单字符生成大量击键。我不知道这是否是一个潜在的问题。

  3. 理想情况下会有一个虚拟键码,它是一个井号,但我没有看到。我错过了吗?

还有其他我没有想到的可能性吗?出于几个原因,我真的需要继续使用SendInput

所以我的问题是,我如何使用SendInput 来模拟正在输入的数字/哈希符号,并使其成为全球性的,并且不依赖于非美国键盘,并尽可能减少击键次数?

谢谢

【问题讨论】:

  • 即使“qwerty”也不意味着“美国布局” - 我的英国布局 qwerty 键盘有一个 Shift-3 的英镑 (£) 符号。
  • 是否需要使用SendInput 而不是SendKeys,顺便说一句?
  • @JonSkeet 谢谢。我更新了我的问题以更具体地了解美国(不是 QWERTY)布局。关于SendKeys,我多年前写了这个库,根据我的回忆,我开始使用MS UIAuto,然后SendKeys,然后SendInput。问题是我需要向许多系统发送击键/填充输入字段,其中一些是 Citrix 和 TermServices 客户端。我不记得我当时遇到的确切问题,但我最终使用了 SendInput(我认为是 Citrix)。我觉得我需要一个支持所有 3 个选项的混合动力车,根据客户要求,也许这就是答案......
  • @AdamPlocher 我希望这可以帮助:我认为您的第三个问题可以解决您的所有问题。对于 CSharp,在您的键盘事件(按键或其他)中,您将看到参数 EventArgs e 或KeyPressEventArgs e etc.. 在你的事件代码中处理这个像 var myNeedChar = e.KeyChar('#').. 然后你会得到实际键盘的 ASCII / UTF-8 / UTF-16 - 无论操作系统使用哪种编码 - 代码equivelant..然后用 keychar 做你项目中需要的东西
  • @JonSkeet 作为一个额外的知识:即使是键盘品牌也可以改变其型号类型本身。我有一个旧的 Logitech-TR(土耳其)键盘。Ctrl+3 是一个欧元符号( €), Shift+3 是 Xor 符号 (^) 和同一个品牌现在 Shift+3 仍然是 Xor 但 Ctrl+3 现在是 Sharp (#)

标签: c# winapi keyboard sendinput


【解决方案1】:

您应该能够使用带有KEYEVENTF_UNICODE 标志的SendInput 来执行此操作。这绕过了 cmets 中讨论的关于不同键盘使用不同扫描码表示数字符号的问题。它有一个普遍认可的Unicode representation

KEYEVENTF_UNICODE 标志应在传递给SendInput 函数的KEYBDINPUT 结构的dwFlags 成员中指定。使用此标志时,您将 wVk 成员设置为 0 并改用 wScan 成员。 The documentation 表示该结构包含更详细的信息。

但这应该很简单。任何设计合理的应用程序都将获取消息(使用GetMessagePeekMessage),然后调用TranslateMessage,这将导致WM_CHAR 消息以适当的Unicode 字符值发布。它甚至可以处理您处理遗留的非 Unicode 应用程序的情况:如果将消息发布到 ANSI 窗口,则 Unicode 值将自动转换为适当的 ANSI 值。这应该不是问题,我能想到的所有字符集都包含数字符号。

或者,您也可以使用VkKeyScanEx function 自己进行翻译以获取字符的虚拟键码,然后使用MapVirtualKeyEx 将此虚拟键码映射到扫描码。不过,我不能确定这是否可行,因为我从未尝试过这种方法。

【讨论】:

  • 科迪,谢谢您 - 我今天早些时候看到了您的回复,但一直忙于扑灭其他火灾。我现在开始研究KEYEVENTF_UNICODE 标志,并会让你知道它是怎么回事。这听起来很有希望!
  • 工作,谢谢!不过,我有点困惑。如果我理解正确,KEYEVENTF_UNICODE 标志会导致SendInputWM_KEYUP/WM_KEYDOWN 消息注入目标句柄。这种行为与我使用wVk 而不使用KEYEVENTF_UNICODE 时的行为是否不同?由于一些奇怪的用例,例如通过 Citrix/TermServ 客户端模拟击键,我很久以前就使用了SendInput。我只是担心这些非标准形式会以不同的方式处理。仍然,回答。谢谢你。此客户不需要 termsrv 客户端功能。
  • @Adam KEYEVENTF_UNICODE 标志的目的是允许您注入 Unicode 字符,而不是虚拟键码。这对于您可能希望像文本输入一样合成手写或语音识别的情况尤其重要。从技术上讲,KEYEVENTF_UNICODE 标志的工作方式与您不使用该标志并指定虚拟键码时非常相似。 KEYEVENTF_UNICODE 实际上发送指定虚拟键代码VK_PACKET 的键盘消息。然后由TranslateMessage 将它们转换为WM_CHAR 相应Unicode 字符的消息。
  • 说了这么多,应该是一模一样的。假设应用程序已正确编写并调用TranslateMessage 而不是尝试进行自己的处理。虽然不可否认,我对 Citrix/etc 一无所知。
  • 再次感谢科迪,这很有帮助。
猜你喜欢
  • 1970-01-01
  • 2013-01-27
  • 2021-02-08
  • 2014-01-07
  • 2010-12-20
  • 2021-03-07
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多