Jump to content
  • Advertisement
Sign in to follow this  
Rodaxoleaux

Win32 Input and GetAsyncKeyState

This topic is 2640 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Windows input has thwarted all my attempts to attempt to even semi-understand it. I've read through the information about the different bits and how the least sign. bit of GetAsyncKeyState only works sometimes (which I suppose shouldn't be used at all since it is not reliable). If I use the function at all, it will work once, for one key, and then all input to that window doesn't register at all. I know I'm doing something wrong programmatically but I can't figure out what.
if (GetAsyncKeyState(VK_F10) >> 8 < 0 || GetAsyncKeyState(VK_F10) >> 1 < 0 || GetAsyncKeyState(VK_F10) < 0)
{
TerminalOn = !TerminalOn;
if (GetFocus() != hwnd)
SetFocus(hwnd);
ToSetWindow = true;
}


I've changed this actually a bunch of times only to produce the same result. Any ideas/advice? (and if that advice is "don't use GetAsyncKeyState()", i'd thank you, but I do need a form of keyboard input that does not rely on focus or the window being shown (as it is hidden when not active))

Share this post


Link to post
Share on other sites
Advertisement
Why do you call the function three times? This changes the behavior of the function, esp. with regards to the least-significant bit, which is well documented. It's also well documented that you basically shouldn't ever test the LSB because it's not reliable.

Also, why are you checking if it's < 0 after shifting bits? What is that supposed to accomplish?

It seems to me like you're just randomly putting things in in hopes that it will work, without actually understanding the function. What happens if you use the canonical example of the function that can be found all over Google as the "correct" usage?

Share this post


Link to post
Share on other sites
Ehm, whatever you are trying and just putting in there is not logical at all, like ApochPiQ said. If you are creating your own window with a callback try to implement some kind of listener which gets information when a WM_KEY or WM_MOUSE is received. Wrap it up in a class which you can use in any other location to get information on a key.

My general input manager goes like this:

switch(uMsg){
case WM_KEYDOWN:
case WM_KEYUP:
{
if( uMsg == WM_KEYUP ) {
SomeListener::SetThisToReleased( wParam );
}else{
SomeListener::SetThisToPressed( wParam );
}
break;
}

case WM_MOUSEMOVE:
{
SomeListener::SetNewMousePosition( wParam, lParam );
break;
}
case WM_LBUTTONUP:
{
SomeListener::SetMousePressed( wParam );
break;
}
case WM_LBUTTONDOWN:
{
SomeListener::SetMouseRelease( wParam );
break;
}
}




Try to split everything up so you can easily manage it when something is wrong. This way of setting up a static listener makes you able to use it throughout the entire project, use key and/or mouse input anywhere you like.

Share this post


Link to post
Share on other sites
I was basically adding random ways once I figured out that the "way that's posted all over Google" doesn't produce the result I want (in other words, the same as what is happening now). I already said the part about the lsb but I thought it was worth a try to try it (and produced the same result), I tried using the WM_KEYDOWN/UP messages but they didn't work after ShowWindow(hwnd,NULL) hiding the window, so I scratched that.

EDIT:: In fact, the normal GetAsyncKeyState() works perfectly as long as there is focus on the window. I'm confused. Isn't it supposed to work regardless?

Share this post


Link to post
Share on other sites
Not necessarily. The reason it exists is, as hinted at by the documentation, largely for backwards compatibility. It isn't really a great way to grab key state, regardless of whether or not your process has input focus.

If you need to monitor input across all processes on the current desktop, try hooks.

Share this post


Link to post
Share on other sites
Indeed. I just read this
Window Visibility
A window can be either visible or hidden. The system displays a visible window on the screen. It hides a hidden window by not drawing it. If a window is visible, the user can supply input to the window and view the window's output. If a window is hidden, it is effectively disabled. A hidden window can process messages from the system or from other windows, but it cannot process input from the user or display output


from the Microsoft website. I will look up more information on hooks. Thanks.


Share this post


Link to post
Share on other sites

Windows input has thwarted all my attempts to attempt to even semi-understand it. I've read through the information about the different bits and how the least sign. bit of GetAsyncKeyState only works sometimes (which I suppose shouldn't be used at all since it is not reliable). If I use the function at all, it will work once, for one key, and then all input to that window doesn't register at all. I know I'm doing something wrong programmatically but I can't figure out what.
if (GetAsyncKeyState(VK_F10) >> 8 < 0 || GetAsyncKeyState(VK_F10) >> 1 < 0 || GetAsyncKeyState(VK_F10) < 0)
{
TerminalOn = !TerminalOn;
if (GetFocus() != hwnd)
SetFocus(hwnd);
ToSetWindow = true;
}


I've changed this actually a bunch of times only to produce the same result. Any ideas/advice? (and if that advice is "don't use GetAsyncKeyState()", i'd thank you, but I do need a form of keyboard input that does not rely on focus or the window being shown (as it is hidden when not active))


Also bear in mind that bitwise operators have low precedence; I cannot remember exactly, but I'm pretty sure that evaluates to:

if (GetAsyncKeyState(VK_F10) >> (8 < 0) || GetAsyncKeyState(VK_F10) >> (1 < 0) || GetAsyncKeyState(VK_F10) < 0){ ... }

Every so often, I forget, and run into a problem where a conditional evaluates differently if I don't put extra parentheses before doing a comparison.

Share this post


Link to post
Share on other sites
You could just use these defines:

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

Share this post


Link to post
Share on other sites

You could just use these defines:

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)



The problem the OP has is related to capturing key state when the program window does not have input focus. Your macros will not help with this, unfortunately.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!