键盘事件:订单是否得到保证

Keyboard events: Is the order guaranteed?

本文关键字:是否 事件 单是否 键盘      更新时间:2023-10-16

对于按下单个键,可以处理多个事件。

有:KeyDownKeyPressedKeyUp

是否保证应用程序将按该顺序接收这些事件?

我的意思是:是单个按键事件的顺序,而不是按下的一系列不同键。

上下文:

在旧版C++应用程序中遇到按键事件问题后我用spy++检查了事件.在那里我看到订单似乎有时不对,keypressed不会每次keydownkeyup都被解雇.

但是,

我确信事件应该完全按照这个顺序触发,但是在互联网上找不到任何东西。所以我在这里提出了这个问题。

请注意,这不是一个多语言问题,但我对C++、Java 和 C# 是否如此感兴趣。

在大多数应用中,它们应该按该顺序发生。 但是,您的窗口可能不会收到输入的每个字符的每个事件。

例如,在 Windows 中,如果按住某个键,则在按键重复时会看到KeyDown和/或KeyPressed,并在释放键后看到单个KeyUp

编辑:

不过,现在我想起来了...Windows 开始时仅将WM_KEYDOWNWM_KEYUP消息发布到窗口(并且仅当您具有焦点时(。 WM_CHAR消息(类似于 KeyPressed 的 Win32 (基于消息循环调用 TranslateMessage 时的消息发布。 这意味着两件事:

  • 如果窗口有消息积压,API 可能只是将消息添加到队列末尾 (IDK(; 这对我来说更有意义(毕竟消息队列是一个队列,而不是一个堆栈(,但它确实意味着如果队列中已经有该键的WM_KEYUP(例如, 如果用户在处理另一条消息时按下并释放了某个键(,则相应的WM_CHAR可能会出现在它之后
  • 像C和C++这样的语言在处理消息方面具有更大的灵活性(阅读:内置自动化较少(;为了获得WM_CHAR消息,它们必须显式调用TranslateMessage或自己进行翻译(除非其他应用程序向其发布此类消息(。 对于后者,不知道消息将以什么顺序发布。

此外,如评论中所述,如果在按下键时焦点切换,您可能只看到KeyUpKeyDown。 (在焦点切换之前,键状态已经是这样了,Windows 可能不会告诉你。 死键(不会自行生成角色的键(根本不会触发KeyPressed(尽管它们通常会触发KeyUpKeyDown(。 他们通常只是等待下一个真实角色并对其进行修改。

所有这些的简短版本:您可以依赖KeyDown事件彼此相关的显示顺序。 与KeyPressed相同,甚至KeyUp。 但是,至少在Windows中,这三种消息类型并没有真正相互协调。 因此,不要假设每个KeyUp都匹配一个KeyDown(反之亦然(,或者KeyPressed出现在KeyUp之前。

您可能还应该决定是要处理字符还是。 我认为,这是这里混乱的一部分;这两者实际上是不同的概念,大多数时候你只真正关心一个或另一个。 据称,Win32会在您处理KeyPressed事件时告诉您密钥代码,但该事件的真正目的是告诉您输入了什么字符。 (它被称为WM_CHAR而不是WM_KEYPRESS是有原因的。 :) 以及为什么 .net 的 KeyPressEventArgs 类型只有KeyChar而不是KeyCode。 另外两个将键盘视为一堆按钮。

如果您是 Windows 用户,这里的经验法则是:通过日志记录或在调试器中检查事件的顺序,然后假设这将始终如此。

这并不完美,但这在 95% 的情况下都有效。我多次听到这样的故事:Windows团队总是推迟改变任何东西,因为100%确定这会破坏某些东西。

这是Windows 2.0时代文档不佳的直接结果。