about bit flags and keyboard

the WM_KEYUP\WM_KEYDOW\WM_CHAR messages are for control the keyboard. and the WPARAM give us the key values.
i understand the WPARAM works in bit flags way... but i continue confuse :(

if(WPARAM==VK_ESCAPE) dosomething;

ok... i can compare 1 key without problems. but imagine that i need compare several keys??? how i can do that? can anyone explain to me, please?
A WM_KEYUP/KEYDOWN/CHAR message will be sent one for each key press. Therefore 1 message = 1 key... and 1 key = 1 message.

Multiple keypresses will be sent via multiple messages. The wParam will ever only represent 1 key at a time.



If you are asking how to check that 1 key for multiple possibilities... then a simple else if or switch statement will suffice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if(wParam == VK_ESCAPE)
{
  // escape pressed
}
else if(wParam == VK_SPACE)
{
  // space bar pressed
}



// ...or...
switch(wParam)
{
case VK_ESCAPE:
    // escape pressed
    break;
case VK_SPACE:
    // space bar pressed
    break;
}
so the only way is to use the GetAsyncKeyState() function, right?q
uhh.. no. You can do it with messages.

Maybe I'm not understanding the question. Can you clarify your problem?
my big objective is:
1 - how i get the 'value'(what keys was pressed... i'm speaking about several\combination keys;
2 - how can i compare what keys was pressed.
ok.. these code works:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool KeyPressed(int a)
{
    if(GetAsyncKeyState(a)!=0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

//using it:
case WM_KEYUP:
            //exit the program
            if(wParam==VK_ESCAPE)
            {
                DestroyWindow(hwnd);
            }
            if(KeyPressed(VK_CONTROL)==true && KeyPressed(13)==true) MessageBox(NULL,"hi","hello",MB_OK);
            return 0;

so what is the problem?
1 - using the GetAsyncKeyState() can i get the bit value?
2 - how can i use letters? or i must use hexadecimal values?
if(GetAsyncKeyState(a)!=0)

This isn't quite right. If you just want the real-time state of the key, you're only interested in the high bit. Do this instead:

if(GetAsyncKeyState(a) & 0x8000)



i'm speaking about several\combination keys


If you want to use modifiers like Ctrl or Alt... then you probably want to use RegisterHotKey and WM_HOTKEY instead of WM_KEYDOWN. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Assign an ID to each hotkey.  Do this with consts or with an enum:
//   note:  do not use negative values
const int Hotkey_Message = 0;

// after you create your window:
RegisterHotKey( your_window, Hotkey_Message, MOD_CONTROL, VK_ESCAPE );
   // now, when the user presses Ctrl+Escape, a WM_HOTKEY message will be generated
   //  and sent to 'your_window' with 'Hotkey_Message' as the wParam


//... then in your message handler
case WM_HOTKEY:
  if( wParam == Hotkey_Message )
    MessageBoxA(your_window, "hi", "hello", MB_OK);
  break;



using the GetAsyncKeyState() can i get the bit value?


Not sure I understand this question. GetAsyncKeyState will tell you if a given key is up or down. If that's what you mean by "bit value", then yes.

how can i use letters? or i must use hexadecimal values?


if(wParam == 'A') // the user pressed the A key



EDIT:

Side note: Your MessageBox call is also wrong. MessageBox takes TCHAR strings, not char strings. You are giving it char strings.

Either put your strings in a TEXT macro to make it a TCHAR string:
MessageBox(wnd, TEXT("hi"), TEXT("hello"), MB_OK );

Or do what I did in my example and call MessageBoxA instead, which takes char strings:
MessageBoxA(wnd,"hi","hello",MB_OK);
Last edited on
thanks for correct me. now i can use the letters correctly ;)
imagine these way: the styles are a bit value. in these value we can test what styles are combined. can i do the same with keys?
the styles are a bit value. in these value we can test what styles are combined. can i do the same with keys?


With modifier keys like Ctrl/Alt/Shift/etc, yes. In above example... when you call RegisterHotKey, you can OR any combination of modifiers you want:

1
2
3
4
5
6
7
8
// Ctrl+Escape
RegisterHotKey( your_window, Hotkey_Message, MOD_CONTROL, VK_ESCAPE );

// Ctrl+Alt+Escape
RegisterHotKey( your_window, Hotkey_Message, MOD_CONTROL | MOD_ALT, VK_ESCAPE );

// just Escape
RegisterHotKey( your_window, Hotkey_Message, 0, VK_ESCAPE );


With other keys, no.
maybe i'm confuse but i belive theres 1 key state function that recive all keys states in a variable, bit way. what you can tell me about it?
like GetKeyboardState() function... but i'm having problems how use it:
1
2
3
PBYTE a;
            GetKeyboardState(*a);
            if(*a==VK_CONTROL & (PBYTE)'A') MessageBox(NULL,TEXT("hi"),TEXT("hello"),MB_OK);
Last edited on
maybe i'm confuse but i belive theres 1 key state function that recive all keys states in a variable, bit way


There isn't. There are too many keys to fit in a single variable.

like GetKeyboardState() function...


GetKeyboardState does not put all key states in a single variable, it puts them in an array.

Also, from reports on MSDN, GetKeyboardState is flakey and unreliable and you probably shouldn't use it (it doesn't do anything unique anyway -- GetKeyState does the same thing, just 1 key at a time).


but i'm having problems how use it:


A PBYTE is a pointer to a byte. You can't just give GetKeyboardState a random pointer... it has to actually point to something. Specifically, you need an array of 256 bytes:

1
2
3
4
5
6
7
BYTE keys[256];
GetKeyboardState(keys);

if( (keys[VK_CONTROL] & 0x80) && (keys[VK_ESCAPE] & 0x80) )
{
  // both Ctrl + Escape are pressed
}


Of course... you can see how this is the same as GetKeyState:

1
2
3
4
5
// equivalent code using GetKeyState:
if( (GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_ESCAPE) & 0x8000) )
{
  // both Ctrl + Escape are pressed
}




Note that both of these are different from using GetAsyncKeyState because GetAsyncKeyState gives you the real-time state of the key, whereas both of the above methods the state is dependent on the processed messages.




Seriously... just use Hotkeys. This is exactly what they're for.
but like you said, the HotKeys are limited.
sorry what means '0x8000'? (and i belive that theres another number too)
but like you said, the HotKeys are limited.


I never said that. In fact they seem to be exactly what you want.

You're basically trying to simulate hotkeys using GetAsyncKeystate... when you should just be using hotkeys directly.


sorry what means '0x8000'? (and i belive that theres another number too)


The '0x' prefix means the number is in hexadecimal.
0x8000 is a 16-bit value with the highest bit being set and all other bits being clear.

IE:
8000 hex ==
1000000000000000 binary

You use this to AND with the returned value from GetAsyncKeyState because:
- GetAsyncKeyState returns a 16-bit value
- The returned value stores the key state in the highest bit
- All other bits either are unused/garbage or contain other information about the key.

By ANDing with the bit we're interested in, we effectively turn all other bits off (force them all to zero) so that we only keep the keystate bit.



0x80 was used with GetKeyboardState because those values are only 8-bit instead of 16-bit.
the RegisterHotKey() 4th argument can't be combined. so the GetAsyncKeystate() can do it ;)
see the function again(because wasn't corrected):
(but i accept sugestions)
1
2
3
4
5
6
7
8
9
10
11
bool KeyPressed(int a)
{
    if(GetAsyncKeyState(a))
    {
        return true;
    }
    else
    {
        return false;
    }
}

and see the sample if:
if (KeyPressed(VK_CONTROL)==true && KeyPressed(VK_MENU)==true && KeyPressed('A')==true && KeyPressed('S')) MessageBox(NULL, TEXT("hi"),TEXT("hello"), MB_OK);
like you see i can combine how many keys i want(good for games and otherthings)... to be honest is what i want: combination free ;)

note: how can i give you 'points'? you help me very... thanks for all
Last edited on
the RegisterHotKey() 4th argument can't be combined. so the GetAsyncKeystate() can do it ;)


I.... I guess....

Are you trying to have a wacky key combo like Ctrl+Q+Z or something? Key modifiers like Ctrl/Alt/etc are really the only ones you'd need to combine normally -- and those can be combined with hotkeys.

and see the sample if:


Yes... since you are doing Ctrl+Alt+A+S, you would not be able to use a hotkey for that. You are right.

(good for games and otherthings)... to be honest is what i want: combination free ;)


The problem with this is that keyboards are not built to handle this. Even if you write your program to handle this... most user's keyboards can only report so many keys down at a time. After that, the keyboard starts "missing" key reports and it will appear as though the user isn't pressing the key when they really are.

Key combos like A+S+Q are not guaranteed to work. And in fact... they frequently break. For this reason. Keyboard designers are under the assumption that keys are going to be pressed one at a time (with a few exceptions). Maybe they'll allow 2 or 3 keys at once.... and it might depend on where they are physically on the keyboard. But in general you should not rely on this.

Exceptions are made for special keys like Ctrl/Alt/Shift, as those are designed to be pressed in conjunction with other keys.


So yeah... even if you do this with GetAsyncKeystate... it might not work depending on the keyboard the user has. It's better to stick with conventional key combos.


note: how can i give you 'points'? you help me very... thanks for all


You can't. There's no rating system on this board.

I'm happy to help. Your thanks is enough reward for me. =)
Topic archived. No new replies allowed.