How do I get the high- and low-order bits of a SHORT?
Asked Answered
S

7

12

The function GetKeyState() returns a SHORT that contains the key's state (up/down in the high-order bit, and toggled in the low-order). How do I get those values?

Synergy answered 14/3, 2011 at 18:0 Comment(0)
I
14

Simple bit manipulation will work. SHORTs are 16-bit integers, so to get the low- and high-order bits you can do the following:

lowBit = value & 1;
highBit = ((unsigned short) value) >> 15;

Also, note that the LOBYTE and HIBYTE macros are used to break SHORTs into low- and high-order bytes, not to test individual bits in a byte.

Intoxicate answered 14/3, 2011 at 18:10 Comment(1)
It is more common to AND with 0x8000 instead of bitshifting.Fernald
B
12

That's not how you use the return value of GetKeyState(). Do it like this instead:

SHORT state = GetKeyState(VK_INSERT);
bool down = state < 0;
bool toggle = (state & 1) != 0;
Bethune answered 14/3, 2011 at 18:16 Comment(2)
thanks hans, but that was an example i just wanted to know how to get the low and high bits of a shortSynergy
value & 0xff* you want bitwise, not logicIaria
F
4

The normal way to check the result of GetKeyState or GetAsyncKeyState is bitwise-and with 0x8000 (binary 1000 0000 0000 0000).

#define IS_DOWN( GetKeyState(x) & 0x8000 )
if( IS_DOWN( VK_ESCAPE ) ) // escape is down.
Fernald answered 26/12, 2012 at 3:36 Comment(0)
W
4

If Google brought you here like it did me while trying to find information on GetKeyboardState() instead of GetKeyState(), note that it acts on an array of BYTE, not SHORT.

  • If you choose to bitwise AND, you should use 0x80, not 0x8000.
  • If you shift, use >> 7, not >> 15.

For example, to determine if either CTRL keys are down:

BYTE keyboardState[256];
GetKeyboardState(keyboardState);
if (keyboardState[VK_CONTROL] & 0x80)
{
    std::cout << "control key!" << std::endl;
}
Wyant answered 7/2, 2018 at 21:24 Comment(0)
H
2
#define LOBYTE(a) ((CHAR)(a))
#define HIBYTE(a) ((CHAR)(((WORD)(a) >> 8) & 0xFF))
Helmholtz answered 14/3, 2011 at 18:6 Comment(2)
do you mean LOSHORT and HISHORT instead of LOBYTE and HIBYTE because those two are already defined in 'Windows.h'Synergy
I think what Dylan is looking for is ChrisV's answer, since the GetKeyState() documentation states that "If the high-order bit is 1, the key is down; otherwise, it is up.". For me that means "the most significant bit". Dylan, basically the LOSHORT/HISHORT macros and the shifting/masking for GetKeyState() are two different things.Iaria
P
1

WORD == SHORT, HIWORD works on DWORDs, HIBYTE works on SHORTs/WORDs.

Placable answered 14/3, 2011 at 18:17 Comment(2)
WORD != SHORT. WORD == unsigned SHORT. For a beginner, there's no reason to assume that HIBYTE, which is documented to accept a WORD, would also accept some other type. It's also not clear whether the result would still be unsigned even though the argument wasn't.Taunton
I guess it doesn't matter because the OP wasn't interested in bytes anyway... Still I think knowing WORD == SHORT is better than not knowing anything about the relation between the two :)Placable
P
0

GetKeyState currently returns SHORT datatype, which typedef from short. short resides within range –32,768 to 32,767. One approach to detect highest enabled bit (key is down) is make it unsigned and then to query against 0x8000 const value.

Another approach is to keep value as signed and simply compare it against 0.

bool bIsKeyDown = GetKeyState(VK_SHIFT) < 0;

Like it's mentioned in here: https://mcmap.net/q/150937/-what-is-the-difference-between-signed-and-unsigned-int

all negative values have highest bit enabled, as all positive values and zero have highest bit disabled.

This is example table for char, but same is applicable to short data type as well, only table will be slightly larger.

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000   -8
1001   -7
1010   -6
1011   -5
1100   -4
1101   -3
1110   -2
1111   -1

And key toggling can be checked using normal "and" operation, like mentioned by other answers here:

bool bIsKeyToggled = GetKeyState(VK_SHIFT) & 1;
Prodigious answered 22/1, 2018 at 12:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.