[英]Keyboard events: Is the order guaranteed?
For pressing a single key, there are multiple events that can be handled. 按下一个键,可以处理多个事件。
There is: KeyDown
, KeyPressed
, KeyUp
. 有:
KeyDown
, KeyPressed
, KeyUp
。
Is it guaranteed that an application will receive those events in that order? 是否保证应用程序将按该顺序接收那些事件?
What I mean is: is the order of a single key pressing event, not a series of different keys pressed. 我的意思是:是单个按键事件的顺序,而不是一系列不同按键的顺序。
Context: 语境:
After I had some problems with keypress-events in a legacy C++ application I inspected the events with spy++
. 在遗留C ++应用程序中的按键事件遇到一些问题之后,我用
spy++
检查了这些事件。 There I saw that the order seems sometimes not to be right and the keypressed
is not fired for every keydown
or keyup
. 在那里,我看到的是,为了看起来有时不是正确的和
keypressed
不闪光时,每keydown
或keyup
。
But, I was sure that the events should be fired in exactly that order, but could not find anything on the internet. 但是,我确定事件应该按照该顺序触发,但在互联网上找不到任何内容。 So I came up with this question here.
所以我在这里提出了这个问题。
Please note that this is not a multiple languages problem, but I am interested whether this is true for C++, Java and C#. 请注意,这不是多种语言的问题,但是我对C ++,Java和C#是否适用很感兴趣。
They should happen in that order when they happen, in most apps. 在大多数应用中,它们应按发生的顺序进行。 But your window might not receive every event for every character entered.
但是您的窗口可能不会为输入的每个字符收到所有事件。
For example, in Windows, if you hold down a key you'll see a KeyDown
and/or KeyPressed
repeatedly as the key repeats, and a single KeyUp
once the key is released. 例如,在Windows中,如果按住某个键,则在重复该键时将反复看到
KeyDown
和/或KeyPressed
,并且在释放键后会看到一个KeyUp
。
Now that i think about it, though...Windows starts out only posting WM_KEYDOWN
and WM_KEYUP
messages to your window (and only if you have focus). 现在,我考虑了一下,但是... Windows开始仅将
WM_KEYDOWN
和WM_KEYUP
消息发布到您的窗口(并且只有在您有焦点的情况下)。 WM_CHAR
messages (the Win32 analogue to KeyPressed
) are posted based on those when the message loop calls TranslateMessage
. 根据消息循环调用
TranslateMessage
时的消息发布WM_CHAR
消息(类似于KeyPressed
)。 This means two things: 这意味着两件事:
WM_KEYUP
for that key in the queue (for example, if the user hit and released a key while another message was being processed), the corresponding WM_CHAR
might appear after it. WM_KEYUP
(例如,用户按下并释放)一个键,而另一个消息正在处理中),相应的WM_CHAR
可能会出现在它后面 。 WM_CHAR
messages, they have to either call TranslateMessage
explicitly or do the translation themselves (barring another app posting such messages to it). WM_CHAR
消息,他们必须显式调用TranslateMessage
或自己进行翻译(除非另一个应用向其发布此类消息)。 With the latter, there's no telling what order the messages will be posted in. Also, as mentioned in the comments, if the focus switches while a key is down, you might only see a KeyUp
or KeyDown
. 另外,如注释中所述,如果在按下某个键时焦点切换了,则可能只会看到
KeyUp
或KeyDown
。 (The key state was already that way before the focus switch, and Windows probably won't tell you about it.) And dead keys (ones that don't generate a character on their own) won't trigger a KeyPressed
at all (though they do typically trigger KeyUp
and KeyDown
). (键状态在焦点切换之前就已经是那样了,Windows可能不会告诉您。)而且,死键(那些不会自行生成字符的键)根本不会触发
KeyPressed
(尽管它们通常会触发KeyUp
和KeyDown
)。 They typically just wait for the next real character and modify it. 他们通常只是等待下一个真实角色并对其进行修改。
Short version of all that : You can rely on the order in which KeyDown
events appear in relation to each other. 所有内容的简短说明 :您可以依赖
KeyDown
事件相对于彼此出现的顺序。 Same with KeyPressed
, and even KeyUp
. 与
KeyPressed
甚至KeyUp
。 But, at least in Windows, the three message types are not really coordinated with each other. 但是,至少在Windows中,这三种消息类型并没有真正相互协调。 So don't assume that every
KeyUp
will match a KeyDown
(or vice versa), or that KeyPressed
appears before KeyUp
. 因此,请不要假定每个
KeyUp
都将匹配一个KeyDown
(反之亦然),或者不要假设KeyPressed
出现在KeyUp
之前。
You should probably also decide whether you want to process characters or keys . 您可能还应该决定是否要处理字符或键 。 That's part of the confusion here, i think;
我认为,这就是这里混乱的一部分。 the two are actually different concepts, and most of the time you only really care about one or the other.
两者实际上是不同的概念,并且在大多数情况下,您实际上只关心其中一个。 While Win32 would allegedly tell you the key code when you're handling a
KeyPressed
event, the real intent of that event is to tell you what character was entered. 据称Win32在处理
KeyPressed
事件时会告诉您键码,但该事件的真正目的是告诉您输入了什么字符 。 (There's a reason it's called WM_CHAR
and not WM_KEYPRESS
. :) And why .net's KeyPressEventArgs
type only has a KeyChar
and not a KeyCode
.) The other two treat the keyboard as basically a bunch of buttons. (有一个原因,它被称为
WM_CHAR
而不是WM_KEYPRESS
。:)以及为什么.net的KeyPressEventArgs
类型仅具有KeyChar
而不具有KeyCode
。)其他两个将键盘基本上视为一堆按钮。
If you are Windows user, the rule of thumb here is: check the order of events by logging or in debugger and then assume that this will be always so. 如果您是Windows用户,这里的经验法则是:通过记录日志或在调试器中检查事件的顺序,然后假定情况总是如此。
This is not perfect, but this works in 95% of cases. 这并不完美,但这在95%的情况下都有效。 I many times heard stories that Windows team always pushes back to change anything because 100% sure this will break something.
我无数次听到Windows团队总是回击更改任何事情的故事,因为100%确保这会破坏某些东西。
This is direct result of poor documentation of the Windows 2.0 era. 这是Windows 2.0时代文档不完善的直接结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.