how to flush or clear GetAsyncKeyState's buffer - c++

i'm using GetAsyncKeyState in an MFC application to check if Esc button is pressed,
but when i press on Esc button from dialog and use GetAsyncKeyState in a different dialog it returns nonzero because it's exists in the message queue.
how can i clear or flush GetAsyncKeyState's buffer or delete this message from message queue?
Thanks in advance.

The direct answer to your question would be just calling it a second time, discarding the value from the first time.
But I guess that what you really want to know is how to read the current status of the key, regardless of when you last checked. Since you wrote "returns nonzero" I believe you are not using it correctly.
You need to check for the bit with value 0x8000 because this one indicates whether it's pressed right now. The bit with the value 1 is the one which is set if the key was pressed since the last check, and that's the one tripping you over, so just ignore it and directly test for the bit with value 0x8000.
Example code:
if(GetKeyState(VK_RETURN) & 0x8000) yayReturnIsPressed();
Checking if(GetKeyState(VK_RETURN)) or if(GetKeyState(VK_RETURN) != 0 will not do what you want because it will be fulfilled if any of the bits in the return value are set.

In GetAsyncKeyState documentation you can read:
If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.
(emphasis mine)
so to check current state of ESC button you should only check most significant bit:
bool isEscPressed = GetAsyncKeyState(VK_ESCAPE) & 0x8000;
if you check state like that: if (GetAsyncKeyState(VK_ESCAPE)) {} then it will enter if statement even if ESC is not currently pressed.

Related

Clear input command line?

I'm making an console application. It starts with a menu where if I press the key; 1. The menu changes into another menu screen. But note, without me pressing 'Enter'. This means that my 1 still remains, which is obviously bad when stepping down further in the menus.
How do I clear the input command line?
The function im using.
if(GetAsyncKeyState('1'))
{
IEventDataPtr gameState(GCC_NEW EvtData_Set_Game_State("PREGAMESTATE"));
em->VTriggerEvent(gameState);
//Enter line clearing code.
}
The function GetAsyncKeyState gives you "the current state of a key". So it will return true between the point when the keyboard driver has received the "key for 1 has been pressed" until the keyboard driver receives "key for 1 has been released".
I would seriously suggest that you use ReadConsoleInput instead if you want to get one keypress at a time.
The alternative is to use something like this:
while(GetAsyncKeyState('1'))
{
// Do nothing.
}
to wait for that key to be released.

X11 Unicode KeyEvent Issues

The program I'm working on a virtual keyboard of sorts that requires unicode. Using the code I've received from http://goo.gl/pv9ht and it works for normal (ASCII) keysyms when converting to a keycode, but XKeysymToKeycode() returns 0 on a keysym like XK_agrave (include/X11/keysymdefs.h).
I'm also not quite sure how to do the same with capitals. When I try the same with XK_A (that's capital 'A'), it returns the same keycode as 'a'. This does make sense since they are the same keycode (along with a bunch of other characters) according to the output 'xmodmap -pke'. But how do I make it send (XSendKeyEvent) the capital form of the keycode?
Help would be much appreciated.
You send with a modifier key (shift in this case)
So you set XKeyEvent->state |= ShiftMask
The state member is set to indicate the logical state of the pointer buttons and modifier keys just prior to the event, which is the bitwise inclusive OR of one or more of the button or modifier key masks: Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask, ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask.
Source: http://linux.die.net/man/3/xkeyevent

movement binding in c++ using ncurses

I can't get this movement binding to work. I'm using the ncurses library, update_ch and oldch are global variables. KEYERR is a macro set to -120 (I just don't handle those keypresses). I'm trying to restrict the player so he can't hold up, down, left, or right, but he has to keep pressing them to move. It's not working, you can still hold the keys down and move. Any suggestions? My logic must be off.
if(update_ch != KEYERR)
{
oldch = update_ch;
}
update_ch = getch();
if(oldch == update_ch)
{
update_ch = KEYERR;
}
I'm trying to restrict the player so
he can't hold up, down, left, or
right, but he has to keep pressing
them to move.
I am pretty sure this isn't possible with curses. If I remember correctly curses only receives characters from a terminal. It doesn't control anything about the process.
Measuring the time between to such readings might give you a hint if the user is holding a key instead of continuously pressing. I mean, when you do a reading, record the following
Key read
Time of read (millisecond precision)
When you read a value, ask the following:
Is it the same as the last key ?
What's the difference between the current time and the time of the last read ?
If it's the same key and the time difference is smaller than some threshold you can decide he's holding the key down.

What does the 0x80 code mean when referring to keyboard controls

what does the 0x80 code mean when referring to the keyboard controls in C++ Windows environment?
For example,
if(GetKeyState('K') & 0x80) {
//do something
}
Thanks everyone!
Update
A flurry of downvotes propelled me into investigating this further. Here's how the return values (in hex) of GetKeyState works. I don't quite get the toggle property of a key like k but I'm assuming there's some default state it toggles from.
0 Default State, key up
ff80 Default state, key down
1 Toggled, key up
ff81 Toggled, key down
So 0xff80 is added whenever the high-order bit needs to be set and the low-order bit makes sense. So now we know why the 0x80 approach works --- since the high-order bit of the lower byte is set as well!
Old Answer
GetKeyState returns a SHORT where if the high-order bit is 1 it means the key is up. The bitwise AND operation with 0x80 just checks if that bit is 1 since in binary 0x80 is 10000000.
Therefore the statement GetKeyState('K') & 0x80 would return 0x80 if the high-order bit of the value returned by GetKeyState('K') is 1 and 0 if the high-order bit is 0.
The MSDN documentation of the function states:
If the high-order bit is 1, the key is
down; otherwise, it is up.
bit-wise and with 0x80 gives you the high order bit, the if checks if the result is zero or non-zero and in essence checks the value of that bit.
This check however looks like a mistake since GetKeyState() returns a SHORT and to check the high order bit of a short you need to bit-wise and with 0x8000.
So I suggest you check the return value with a debugger and verify how this works in reality.
I think you mean 0x8000, not 0x80. If that is the case, you should consult the documentation (http://msdn.microsoft.com/en-us/library/ms646301(VS.85).aspx) which has the following to say on the return value of GetKeyState:-
The return value specifies the status of the specified virtual key, as follows:
•If the high-order bit is 1, the key is down; otherwise, it is up.
•If the low-order bit is 1, the key is toggled. A key, such as the CAPS LOCK key, is toggled if it is turned on. The key is off and untoggled if the low-order bit is 0. A toggle key's indicator light (if any) on the keyboard will be on when the key is toggled, and off when the key is untoggled.
0x80 doesn't mean anything as far as I know though
According to the documentation
The return value specifies the status of the specified virtual key:
If the high-order bit is 1, the key is down; otherwise, it is up.
If the low-order bit is 1, the key is toggled. A key, such as the CAPS LOCK key, is toggled if it is turned on. The key is off and untoggled if the low-order bit is 0. A toggle key's indicator light (if any) on the keyboard will be on when the key is toggled, and off when the key is untoggled.
Perhaps with a non-toggleable key (such a 'K'), the low-order (ambiguous term - perhaps they mean 0x0080 ?) and high-order (0x8000) bits do the same thing?

Using SetKeyboardState along with GetKeyboardState in C++

I don't know how to write a good question here, but, basically, does anyone know where I can possibly find some C++ source code using these to actually set keyboard state? For some reason using it the way MSDN does on Windows 7 doesn't do...anything at all.
Basic code:
PBYTE keyState;
GetKeyboardState(keyState);
...
// Later on when I need to set the keyboard state (key pressed etc) back to original:
SetKeyboardState(keyState);
and ... nothing happens :(
From:
http://www.gamedev.net/community/forums/topic.asp?topic_id=43463
First off, GetKeyboardState() would be the wrong function to use because as Windows has a chance to process keyboard messages (whether you want it too or not) it updates the results of the keyboard's state for the next call to GetKeyboardState().
Here's a little function that I use to get the status of the keyboard's keys. Be carefull though, depending on how fast your main loop is, it may cause problems if you aren't expecting it.
You need to keep track of whether or not a specific key was pressed the last time you called the ReadKeyboard() function. If your loop polls the keyboard 30 times a second, then pressing a key once probably causes the key to be flagged 3 or 4 calls in a row. Rather confusing sometimes. Just thought I'd mention it.
void ReadKeyboard( char* keys )
{
for (int x = 0; x < 256; x++)
keys[x] = (char) (GetAsyncKeyState(x) >> 8);
}