使用`SendInput`时,如何处理郁闷的Windows徽标键?

我的应用程序通过使用SendInput在其他应用程序中合成击键。 这几乎可以工作,除了由于情况我不能改变,发送input时左侧的Windows键总是被物理压低。 这意味着,例如,如果发送的按键是“d”键,则Windows将键击看作其Win + D快捷键并显示桌面,而“d”键击从不将其置于其预定目标。

文档中提到了这个问题,但是如何解决这个问题令人沮丧(我的重点):

此function不会重置键盘的当前状态。 调用函数时已经按下的任何键都可能会干扰此函数生成的事件。 为避免此问题,请使用GetAsyncKeyState函数检查键盘的状态,并根据需要进行更正

我应该如何“根据需要进行纠正”?

我已经尝试使用SetKeyboardState来closuresVK_LWIN键的键盘状态,在第一次将我的线程连接到我正在发送键击(与AttachThreadInput )的窗口的线程后,但这似乎不影响行为在所有。

我也尝试在我用SendInput发送的input开始处插入一个KEYEVENTF_KEYUP事件,但是这会导致开始菜单popup并抓住焦点,这显然是不可接受的。

调用SendInput时,处理郁闷的Windows徽标键的正确方法是什么?

编辑:

根据@ Brian的回答,我可以通过安装捕获win-key keydown事件的低级别keyhook来防止win key干扰我的代码。

但是,这具有意外的效果,即Windows键现在完全禁用。 我可以设想一些解决scheme,在这里我记住了我的钥匙扣内的所有钥匙的状态,当按下其他钥匙时模拟按下窗口钥匙,这取决于它们是否是我的钥匙模拟,但这听起来像对我来说是一个黑客。 或者,我可以使用我的键盘来模拟重要的Windows键盘快捷键。

但是文件意味着它应该以更直接的方式工作。 布赖恩的解决scheme是防止赢钥匙进入按下状态。 但是文档指出,你应该能够检查它是否被按下,如果是的话就更正。

这实际上是可能的吗?

Solutions Collecting From Web of "使用`SendInput`时,如何处理郁闷的Windows徽标键?"

我基本上解决了这个确切的问题昨天 :)我的代码是在C#中,但它主要是通过p / invoke调用win32 API,所以它应该直接转换为C ++。

解决方法是使用低级别键盘钩子截取最初的Windows键盘事件(并告诉操作系统,您处理它,以便它不会传递给其他应用程序和/或操作系统)。 然后,根据操作系统,在输入之前模拟Windows KeyUp事件。 这听起来像是你的中途,你只需要拦截最初的KeyDown。

我的解决方案是针对Windows Vista和Windows 7的,所以如果您使用的是XP或更低版本,则可能无需发送KeyUp。 这就是我将要测试的,它可能在两个方面工作。 然而,Vista和7比XP更加积极地拦截Windows密钥,因此我怀疑。

没有一个更直接的方法来让程序在不修改注册表的情况下执行此操作。 理想的解决方案是跟踪表中的按键(std :: map,Dictionary等)。 MS的目的是防止病毒/恶意软件控制键盘,并防止用户使用重要的键盘组合,如WinKey-L和Ctrl-Alt-Delete。

但是,如果键盘钩子不适合您,则可以重新映射注册表中的键盘扫描代码。 这是不理想的,因为很难反转(特别是如果你犯了一个错误,或者你的程序崩溃了,或者用户卸载了应用程序,但注册表黑客没有被还原)。 但它确实有效。 这里有一些参考:

http://www.howtogeek.com/howto/windows-vista/map-any-key-to-any-key-on-windows-xp-vista/

http://www.howtogeek.com/howto/windows-vista/disable-caps-lock-key-in-windows-vista/

http://www.usnetizen.com/fix_capslock.php