要按一个键,可以处理多个事件。
有KeyDown
,KeyPressed
,KeyUp
。
是否保证应用程序将按该顺序接收这些事件?
我的意思是:是一键按下事件的顺序,而不是按下一系列不同的按键。
上下文
在遗留C ++应用程序中遇到keypress-events时出现问题
我用spy++
视察了这些事件。在那里,我看到订单似乎有时候
不正确,keypressed
或keydown
不会触发keyup
。
但是,我确信事件应该按照那个顺序被触发,但是 在互联网上找不到任何东西。所以我在这里提出了这个问题。
请注意,这不是多语言问题,但我对C ++,Java和C#是否属实感兴趣。
答案 0 :(得分:4)
在大多数应用中,它们应该按顺序发生。但是,对于输入的每个字符,您的窗口可能不会收到每个事件。
例如,在Windows中,如果您按住某个键,则会在重复键时重复显示KeyDown
和/或KeyPressed
,并在键重复时显示一个KeyUp
被释放。
现在我考虑一下,但是...... Windows开始时只向您的窗口发布WM_KEYDOWN
和WM_KEYUP
条消息(只有当您有焦点时)。 WM_CHAR
消息(Win32类似于KeyPressed
)根据消息循环调用TranslateMessage
时的消息发布。这意味着两件事:
WM_KEYUP
队列(例如,如果用户在处理另一条消息时点击并释放了一个键),相应的WM_CHAR
可能会在之后出现。WM_CHAR
条消息,他们必须明确地调用TranslateMessage
或自己进行翻译(除非另一个应用程序向其发布此类消息)。对于后者,无法确定消息的发布顺序。此外,正如评论中所述,如果在关键功能关闭时焦点切换,您可能只会看到KeyUp
或KeyDown
。 (关键状态在焦点切换之前已经是这样了,Windows可能不会告诉你它。)死键(不能自己生成字符的那些)不会触发{{1}完全(尽管它们通常会触发KeyPressed
和KeyUp
)。他们通常只是等待下一个真正的角色并进行修改。
所有的简短版本:您可以依赖KeyDown
事件相对于彼此出现的顺序。与KeyDown
相同,甚至与KeyPressed
相同。但是,至少在Windows中,这三种消息类型并不真正相互协调。因此,不要假设每个KeyUp
都匹配KeyUp
(反之亦然),或者KeyDown
出现在KeyPressed
之前。
您可能还应决定是否要处理字符或键。我认为这是混乱的一部分;这两者实际上是不同的概念,大多数时候你只关心其中一个。据称Win32会在您处理KeyUp
事件时告诉您关键代码,但该事件的真正意图是告诉您输入的字符。 (这有一个原因叫它KeyPressed
而不是WM_CHAR
。:)为什么.net的WM_KEYPRESS
类型只有KeyPressEventArgs
而不是KeyChar
。)其他两个对待键盘基本上是一堆按钮。
答案 1 :(得分:0)
如果您是Windows用户,这里的经验法则是:通过记录或在调试器中检查事件的顺序,然后假设这将始终如此。
这并不完美,但这在95%的情况下有效。我多次听过Windows团队总是推迟改变任何事情的故事,因为100%肯定会破坏某些东西。
这是Windows 2.0时代文档记录不佳的直接结果。