【发布时间】: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 被按下”消息后注册一个回调以运行),看看是否能解决您的问题。