当指定 RIDEV_NOLEGACY 时,Win32 原始输入会阻止输入区域设置切换

Win32 raw input blocks input locale switching when RIDEV_NOLEGACY is specified

我正在为Windows写一个基于Raw Input的键盘输入系统。它是通过 RIDEV_NOLEGACY 标志集实现的,并且只有在客户端未处理输入时才会手动生成传统键盘消息。

我已经设法让它工作了,但是语言切换热键(在我的例子中是 Alt+Shift)现在坏了。

系统必须:

  1. 区分不同的输入设备;

  2. 检测设备[断开]连接;

  3. 允许处理程序使用输入,防止它被优先级最低的处理程序处理;

  4. 保持 alt codes 功能;

  5. 如果可能,保持 accelerators 系统键也能正常工作;

我尝试了多种原始输入设置组合,但每一种都违反了一些要求。现在的主要问题是 3.

使用 RIDEV_NOLEGACY 处理程序可以使用 WM_INPUT 或不处理。在第二种情况下,系统自己生成 WM_[SYS]KEYUP / WM_[SYS]KEYDOWN 消息并通过 PostMessage 发布。由于 PostMessage 不更新线程的键盘状态,系统也会在适当的地方更新它。所以 3、4 和 5 都可以。但是 Alt+Shift 停止响应。

没有 RIDEV_NOLEGACY Alt+Shift 会按预期更改语言环境,但原始输入会生成旧版 WM_[SYS]KEYUP / WM_[SYS]KEYDOWN,无论是否有客户端处理 WM_INPUT与否。

有一个问题的最小工作示例: https://github.com/niello/misc/tree/master/RawInputLocale

在 Win10 和 Win8.1 上重现,但可能在自 Vista 以来的任何 Windows 上都相同。

请注意,如果您在示例中将 USE_NOLEGACY_RAW_INPUT 设置为 true,WM_CHAR 消息仅针对每秒钟击键生成,就好像另一个击键是由我们的系统客户端使用,但如果您尝试更改输入语言环境,则什么也不会发生。如果您将 USE_NOLEGACY_RAW_INPUT 设置为 false,您将正常切换语言环境并接收 WM_INPUTLANGCHANGE,但也会为消耗的击键生成 WM_CHAR。

我 运行 没有想法,所以任何帮助将不胜感激。

又过了一天,似乎没有简单的解决办法。 RIDEV_NOLEGACY 只是通过热键杀死了语言切换。好消息是所有必要的逻辑都可以手动实现。这是我现在的解决方案。它考虑了系统热键设置,当“`”键用作热键时抑制字符生成,甚至无需重新启动应用程序即可检测系统热键更改。 该代码在同一 repo 中可用。 希望这也会对其他人有所帮助。

我认为使用 RIDEV_NOLEGACY 进行键盘和鼠标原始输入是不值得的 - 您可以忽略应用中的这些“遗留”WM_KEY*/WM_MOUSE* 消息。这种 no legacy 模式存在问题,并且没有明显的性能提升。 同样适用于 RIDEV_CAPTUREMOUSE.