简体   繁体   中英

Keyboard events: Is the order guaranteed?

For pressing a single key, there are multiple events that can be handled.

There is: 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++ . There I saw that the order seems sometimes not to be right and the keypressed is not fired for every keydown or 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#.

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.

Edit:

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). WM_CHAR messages (the Win32 analogue to KeyPressed ) are posted based on those when the message loop calls TranslateMessage . This means two things:

  • If the window has a backlog of messages, the API might just add the message to the end of the queue (IDK); this makes more sense to me (the message queue being a queue , after all, and not a stack), but it does mean that if there is already a 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.
  • Languages like C and C++ have more flexibility (read: less built-in automation) in how they handle messages; in order for them to get WM_CHAR messages, they have to either call TranslateMessage explicitly or do the translation themselves (barring another app posting such messages to it). 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 . (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 ). 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. Same with KeyPressed , and even KeyUp . But, at least in Windows, the three message types are not really coordinated with each other. So don't assume that every KeyUp will match a KeyDown (or vice versa), or that KeyPressed appears before 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. (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.

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.

This is not perfect, but this works in 95% of cases. I many times heard stories that Windows team always pushes back to change anything because 100% sure this will break something.

This is direct result of poor documentation of the Windows 2.0 era.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM