【问题标题】:Simulate Ctrl-button pressed模拟按下 Ctrl 键
【发布时间】:2014-01-30 12:08:33
【问题描述】:

我正在模拟按下的 Ctrl 按钮:

[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

keybd_event(VK_CONTROL, 0, 0, 0); //key down
/* Stuff which needs ctrl to be pressed is done here */
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0); //key up

此代码位于 .dll 文件中。该 dll 在 WPF 应用程序中使用。现在我有奇怪的行为,只有当 WPF 窗口不活动时,按下的 Ctrl 键才会被识别。这意味着当我单击另一个窗口以停用 WPF 窗口并强制运行代码而不再次激活 WPF 窗口时,它可以工作。点击 WPF 窗口后,它不再工作了。

有什么想法吗?

编辑: 我将代码从 dll 移到了 wpf 应用程序,它没有改变任何东西。在我测试的 WPF 应用中:

keybd_event(VK_CONTROL, 0, 0, 0);
child.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);

【问题讨论】:

  • 你为什么要为此使用 dll 导入?
  • 因为无论如何我都将它用于其他一些东西。但我也尝试了不同的解决方案来提高按键向下/向上事件。所有解决方案都导致相同的行为。
  • keybd_event 是异步的。使用SetKeyboardState。将所有 256 个字节设置为 0,除了索引 VL_CONTROL 处的字节(设置为 -128 或 0x80)。同步 RaiseEvent 后再次使用全部为 0
  • 我猜你已经看过C# Simulate Key Press 的帖子了……有吗?如果这没有帮助,请查看 CodePlex 上的 Windows Input Simulator (C# SendInput Wrapper - Simulate Keyboard and Mouse) 项目。我的最后一个产品是来自 MSDN 的 How to: Simulate Mouse and Keyboard Events in Code 页面,它使用 SendKeys 类来做你想做的事。
  • manuell 很好地指出了 keybd_event 是异步的——然后你调用 RaiseEvent,我相信它是同步的。因此,您在您的应用程序有机会处理“CTRL 被按下”消息之前调用您的事件。尝试将RaiseEvent 调用封装在Dispatcher.BeginInvoke 中(即,在处理完“CTRL 被按下”消息后注册一个回调以运行),看看是否能解决您的问题。

标签: c# wpf winapi events


【解决方案1】:

manuell 在我的问题的第三条评论中提到了一个解决方案并解释了问题:

keybd_event 是异步的。使用 SetKeyboardState。将所有 256 个字节设置为 0,除了索引 VL_CONTROL 处的字节(设置为 -128 或 0x80)。在同步 RaiseEvent 之后再次使用全部为 0 – manuell

Joe Whites 进一步解释并提出了一个可能很好的解决方案:

manuell 很好地指出了 keybd_event 是异步的——然后你调用 RaiseEvent,我相信它是同步的。因此,您在您的应用程序有机会处理“CTRL 被按下”消息之前调用您的事件。尝试将 RaiseEvent 调用包装在 Dispatcher.BeginInvoke 中(即,注册一个回调以在处理完“CTRL 被按下”消息后运行),看看是否能解决您的问题。 – Joe White

谢谢!

【讨论】:

    猜你喜欢
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多