Skip to main content
GameDev.net gamedev.net
🔒 Locked

wm_keydown, or GetAsyncKeyState?

Started by xXShadowAsasNXx Apr 14, 2009 at 8:29 PM 10 replies 10.8k views
Original Post
xXShadowAsasNXx
xXShadowAsasNXx
Hi, I am currently making a game engine, and am about to create an "input" module for it. I know that wm_keydown gives you the scan code, but isn't it not able to tell the difference between l shift and r shift??? Is GetAsyncKeyState slower or faster that wm_keydown? I know about wm_char for ascii codes, and wm_input for high def mouse input, so don't tell me about those. Please tell me which i should use!
Colin Jeanne
Colin Jeanne
WM_KEYDOWN will also give you the virtual key code, of which there are VK_LSHIFT and VK_RSHIFT. Whether you use WM_KEYDOWN or GetAsyncKeyState() depends on the structure of your game. If you are doing processing for you game's state in your window procedure then WM_KEYDOWN is probably a good bet.
Ravyne
Ravyne
Not sure about GetAsyncKeyState, but I know that Microsoft recommends the standard WM_KEYDOWN method over even keyboard handling through DirectInput, so I'd say that WM_KEYDOWN is probably the preferred method across the board.
throw table_exception("(? ???)? ? ???");
Aardvajk
Aardvajk
GetAsyncKeyState() also does not respect whether your application has keyboard focus, so if it is checking and responding in a loop but not the focused window, it will continue to respond to the keyboard.

I wouldn't have thought there is any significant speed consideration at all between the two approaches as your WndProc will be receiving WM_KEYDOWN and WM_KEYUP messages anyway, just passing them on to DefWindowProc and ignorning them if you don't handle them.
brownhead
brownhead
GetAsyncKeyState is meant to be used, as its name implies, in asynchronous applications where it may be inconvenient or impossible to check the Window's queue for user input. However, due to the fact that other applications can call GetAsyncKeyState and catch a keystroke instead of your application, it should be avoided. It's one of the functions in Window's API that seems to be completely pointless.

My vote goes for finding a way to check the queue for WM_KEYDOWN and WM_KEYUP messages and handle them accordingly. A much more reliable way of handling user input, and will end up giving you an easier time.

The speed of either method completely depends on the structure of your program, neither is faster.
adam4813
adam4813
GetAsyncKeyState has its uses though. Lets say before you start your application the user is holding the 'A' key. You application will never receive a WM_KEYDOWN for the 'A' key. What if you application does something different, like maybe a safe mode, when the 'A' key is held during start-up.
brownhead
brownhead
Quote:
Original post by adam4813
GetAsyncKeyState has its uses though. Lets say before you start your application the user is holding the 'A' key. You application will never receive a WM_KEYDOWN for the 'A' key. What if you application does something different, like maybe a safe mode, when the 'A' key is held during start-up.
Well this could produce some unpredictable behavior, if the user has pressed A at any point since any program has called GetAsyncKeyState, the key will be shown as pressed.
Much better to use GetKeyState instead in that situation.
Codeka
Codeka
Quote:
Original post by brownhead
Well this could produce some unpredictable behavior, if the user has pressed A at any point since any program has called GetAsyncKeyState, the key will be shown as pressed.
Much better to use GetKeyState instead in that situation.
There are two bits that GetAsyncKeyState sets, the most significant bit, and the least significant bit. The least significant bit works like you say, but the most significant bit is the one that most people actually use - the most significant bit tells you whether the key is currently, at this very instant up or down.
brownhead
brownhead
Quote:
Original post by Codeka
I'm not sure you understand how GetAsyncKeyState works. If you call GetAsyncKeyState('A'), then it will return a value that tells you whether the "A" key is currently down (or up). It's totally irrelevent whether another application also calls GetAsyncKeyState('A') at the same time.
Hmm, I just read through the documentation again and I take back what I said before about a key being caught that was pressed previous to the call. That functionality was deemed obsolete, and can be safely ignored.
However, looking into it more has only convinced me more of GetAsyncKeyState's uselessness, I think GetKeyState should be used in every case where one might use GetAsyncKeyState, and I'm going to bet that GetAsyncKeyState adds some overhead that isn't needed. The only difference I can see between the two is that the asynchronous version adds the extra obsolete functionality.
Codeka
Codeka
Quote:
Original post by brownhead
Quote:
Original post by Codeka
I'm not sure you understand how GetAsyncKeyState works. If you call GetAsyncKeyState('A'), then it will return a value that tells you whether the "A" key is currently down (or up). It's totally irrelevent whether another application also calls GetAsyncKeyState('A') at the same time.
Hmm, I just read through the documentation again and I take back what I said before about a key being caught that was pressed previous to the call. That functionality was deemed obsolete, and can be safely ignored.
However, looking into it more has only convinced me more of GetAsyncKeyState's uselessness, I think GetKeyState should be used in every case where one might use GetAsyncKeyState, and I'm going to bet that GetAsyncKeyState adds some overhead that isn't needed. The only difference I can see between the two is that the asynchronous version adds the extra obsolete functionality.
Heh, you might notice I revised my post as well after reading the documentation more :-) I've only ever used GetAsyncKeyState in the way I described: to get the "current" state of the key by examining the high order bit. I never knew the "was the key pressed since the last call to GetAsyncKeyState" feature existed until I read your post (and then read MSDN a bit more closely)...

In any case the advantage of GetAsyncKeyState over GetKeyState is that GetKeyState only works if your thread has an input queue associated with it. It doesn't work if you don't have a window on your thread and it also doesn't return information about key presses that happen while another thread had the input focus. GetAsyncKeyState returns the current (as in hardware-level) state of the keyboard. So there clearly is a use for it.

Of course, you can miss keystrokes with GetAsyncKeyState (if the user pressed and then released the key beteween calls to GetAsyncKeyState, and another thread calls GetAsyncKeyState and "swallows" the low-order bit). But that's not the purpose of GetAsyncKeyState anyway - it's purpose is to tell you the current hardware state of the keyboard. Past presses/releases should not be considered.
brownhead
brownhead
Haha, well looks like we were both confused. I guess GetAsyncKeyState is indeed useful :-). Thanks for looking into it, I gotta get better at reading MSDN 0.o
Codeka
Codeka
No problem :-)

Just for the OP's sake, to summarize, I think WM_KEYDOWN/WM_KEYUP is probably the solution for keyboard events in a game. I can't imagine a situation where GetAsyncKeyState would be any more beneficial (you've already got an input queue and a window so you're already processing the WM_KEYDOWN/WM_KEYUP events)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.