【问题标题】:Create an On-screen Keyboard创建屏幕键盘
【发布时间】:2011-02-09 12:06:34
【问题描述】:

我使用 PostMessage 在后台程序中模拟击键。除了需要在物理键盘上移动的字符外,它工作正常。如何模拟班次? "

我使用的代码大致是:

 VK vk = VkKeyScanEx (c, GetKeyboardLayout (0));

 AttachThreadInput (_attachedThredId, _attachedProcessId, true);
 PostMessage       (_window, WM_KEYDOWN, vk.key, 0x1);
 PostMessage       (_window, WM_KEYUP,   vk.key, 0xC0010001);
 AttachThreadInput (_attachedThredId, _attachedProcessId, false);

我应该如何处理 VK 的扩展部分?

编辑

我正在尝试创建一个屏幕键盘。屏幕键盘上的每个按钮都模拟一系列击键。接收器是一个旧程序,它根据执行的键盘顺序执行不同的任务。 键盘顺序如下

  • {ESC}NN{ESC}NN
  • {ESC}NN
  • ½NN
  • §NN

其中 {ESC} 模拟按下 Esc 键,NN 是十六进制值,§/½ 让程序监听。

通常我们有特殊的物理键盘来控制程序,但它们很贵。所以在我们并不总是有物理键盘的测试环境中,我们必须手动输入这些代码

【问题讨论】:

  • 不要使用 PostMessage!它不起作用。使用 SendInput。
  • 我现在已经描述了更多我尝试做的事情。希望你能帮助我

标签: c# c++ winapi


【解决方案1】:

你必须妥协:

如果你想模拟键盘输入,那么你必须使用SendInput,这意味着要受哪个窗口当前具有焦点的支配。 SendInput 就像敲击物理键盘上的键。使用键盘将击键发送到特定窗口的唯一方法是 ALT+TAB 到右侧窗口。

如果您想将击键发送到特定窗口,那么您会招致时髦的行为:

  1. 应用程序处理输入的方式不同。而简单的WM_KEYDOWN / WM_KEYUP 消息并不是检测键盘输入的唯一方法。例如,还有键盘状态 (GetKeyboardState()),您将难以模拟。这很可能是您遇到的情况。
  2. 应用程序在接收键盘输入消息时可能依赖于获得焦点的标准行为。通过向这些应用程序发布消息,您会调用可能导致它们崩溃的奇怪的无序行为。
  3. 现在系统上的多个窗口可以同时接收键盘输入。这也可能导致奇怪的行为。
  4. (等...)不会为此输入调用挂钩,您的键盘/输入驱动程序不会看到它,它不会被 DirectInput 之类的东西识别...基本上这是一个永无止境的拼凑通过做坏事来解决问题。

没有办法解决这些副作用;这是做黑幕的后果。


适合您的解决方案,因为您针对的是单个特定应用程序,所以可能是使用 PostMessageSetKeyboardState 来模拟键盘状态,包括移位位置。 p>

【讨论】:

  • 我已经测试了 SetKeyboardState,但如果我做错了什么,我现在不会。它不起作用
【解决方案2】:

好吧,我想你在这里搞砸了,PostMessage()not working well with shift states 而臭名昭著,而且钩子也不会被调用。微软推荐SendInput(),我也推荐。我建议你发布一个新问题,或者更新这个问题,在其中详细说明你想要实现的目标,也许我们可以更好地推荐一个不同的解决方案。

至于扩展部分,和这个完全没有关系,也帮不了你。

可以尝试的方法是发送一条 WM_KEYDOWN 消息,说明按下了 shift 键,然后在发送 WM_KEYUP shift 消息之前使用您想要的键发送另一条消息。我怀疑这会奏效,但您可以随时尝试。

【讨论】:

  • 我现在已经描述了更多我尝试做的事情。希望你能帮助我
  • 您仍然需要使用SendInput。我们已经了解您想要做什么。您不需要修改问题,您需要阅读答案!
  • @magol:您可以尝试激活要发送输入的窗口,使用ShowWindow(SW_NOACTIVATE) 将您自己的窗口设置为未激活的前台,然后使用SendInput() 模拟输入。当用户在您的屏幕键盘上按下一个新键时,您的应用程序应该再次获得焦点,并重复该过程。这应该可行,AFAIK,但我从未尝试过......
  • 我确实测试了 ShowWindow(SW_NOACTIVATE),但我的窗口没有到前面。
  • @magol:您最好开始一个新问题“如何在不激活它的情况下将我的窗口设置为前台”并用它发布一些代码。有很多事情可以起作用。其中之一是将您的窗口临时设置为“最顶层”,然后立即撤消。
【解决方案3】:

我个人会为此目的使用 SendKey.Send()。

MSDN page

【讨论】:

  • 来自 MSDN:将击键发送到 活动应用程序。我发送击键的应用程序未激活,因此我无法使用它:-(
  • +1,你不能让它与 PostMessage() 一起工作。时期。使窗口处于活动状态。
  • 我现在已经描述了更多我尝试做的事情。希望你能帮助我
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 2016-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多