[MS] Customizing the ways the dialog manager dismisses itself: Detecting the ESC key, first (failed) attempt - devamazonaws.blogspot.com
Suppose you want to distinguish between dismissing a dialog by pressing ESC and dismissing a dialog by clicking the Close button. One suggestion I saw was to call GetAsyncKeyState( to check whether the ESC is down.
In general, any time you see GetAsyncKeyState, you should be suspicious, since GetAsyncKeyState checks the state of the keyboard at the moment it is called, which might not be relevant to your window if it asynchronously lost keyboard focus, and which (from the point of view of your program) might even be from the future.
Recall that the system maintains two types of keyboard states. One is the synchronous keyboard state, which represents the state of the keyboard as far as your program is aware. If your program received a WM_ for the space bar, then GetKeyState will report that the space bar is pressed. Even if the user releases the space bar, GetKeyState will continue to report that the space bar is pressed until the program receives a WM_ for the space bar.
The idea here is that your program is processing an input stream, and due to the nature of multitasking and the physics of time, it's possible that your program is catching up to input that actually occurred some time ago. For example, maybe the user typed ahead into the program while it was unresponsive, and now that the program has become responsive again, it is playing catch-up with all the typing that occurred 30 seconds ago.
If the program receives, say, a press of the F2 key and wants to know whether to do the Ctrl+F2 hotkey, it doesn't know want to know whether the Ctrl key is down at the moment it is processing its input backlog. It wants to know whether the Ctrl key was down at the time the F2 was pressed.
| Time | Event |
|---|---|
| 1 | User presses Ctrl |
| 2 | User presses F2 |
| 3 | User releases F2 |
| 4 | User releases Ctrl |
| 5 | Program receives Ctrl down |
| 6 | Program receives F2 down |
| 7 | Program uses GetAsyncKeyState to ask if Ctrl is downAnswer: No Program does F2 action instead of Ctrl+F2 |
When the program asks via GetAsyncKeyState whether the Ctrl key is down, the answer is "No, it's not down. It was released at some future point in time you haven't learned about yet." And so the program does its F2 action instead of Ctrl+F2, and you get a bug report that goes like "When the program is under heavy load, the Ctrl+F2 hotkey doesn't work."
Suppose your program wants to discard changes when the user dismisses the dialog with ESC but wants to save changes when the user dismisses the dialog with the Close button. Checking the asynchronous state of the ESC key will tell you whether the ESC is down right now, but not whether the ESC was down at the time the system generated the IDCANCEL. You're going to get bugs like, "When the program is under heavy load, pressing ESC to dismiss the dialog sometimes saves the changes instead of discarding them."
Of course, the bug report probably isn't going to be so kind as to mention that the program was under heavy load or that the ESC accidentally saved the changes. It'll probably just say "Sometimes I see changes that I'm sure I had discarded." And you'll have to figure out what the necessary conditions are for that bug to manifest itself.
Bonus chatter: I don't know why people love to use GetAsyncKeyState so much. It has a longer, more cumbersome name than the largely-ignored GetKeyState function. Maybe people think that the longer, more cumbersome name means that it's somehow "more fancy".
Post Updated on February 20, 2026 at 03:00PM
Thanks for reading
from devamazonaws.blogspot.com
Comments
Post a Comment