Archived

This topic is now archived and is closed to further replies.

MattS423

Macros and GetAsyncKeyState()

Recommended Posts

hey guys... can somebody tell me how this macro works?
    

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


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

    
i didn't quite understand the macro Definitions. also the book i'm reading says "you simply send the function [GetAsyncKeyState()] the virtual key code that you want to test, and if the high bit of the return value is 1, the key is pressed". now, the return value for GetAsyncKeyState is a SHORT. I assume a SHORT is a 2-bit interger. How do I check the high bit of a SHORT? (i assume it has something to do with < ? 0:1 > in the source above) thanks guys... --MattS423 edit: source code spacing [edited by - MattS423 on November 1, 2002 2:46:13 PM]

Share this post


Link to post
Share on other sites
Macros work basically as 'find-and-replace' mechanism to simplify the code you have to write.

You have probably seen basic #define macros, for example:


#define A_NUMBER 0.016237523004432


Following this macro definition, every time you write the text "A_NUMBER" (without quotes) in your code, the compiler program replaces it with the text "0.01623752300432" (without quotes) before it actually compiles the code. This 'find and replace' process is carried out by the preprocessor.

Macros can also take parameters. a bit like functions. For example


#define TIMES_BY_TWO(x) x*2


so this...

int ANumber = 7;
int MyNumber = TIMES_BY_TWO(ANumber);
AnotherNumber=TIMES_BY_TWO(8);


will become

int ANumber = 7;
int MyNumber = ANumber*2;
AnotherNumber=8*2;


So, using your your macro

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


this code:


if(KEYDOWN(VK_SPACE))
{
//...
}


becomes this:


if(((GetAsyncKeyState(VK_SPACE) & 0x8000 ? 1 : 0))
{
//...
}



As for bit testing, the way to test if a bit is set is to "bitwise and" (using the "&" operator) it with a mask consisting of the bit to want to test. E.g


// test bit 0 (use mask value 0x0001) which is
// 0000000000000001 in binary)
if( (Number & 0x0001) != 0 )
{
// first (bottom) bit is set
}

// test bit 2 (use mask value 0x0004 which is
// 0000000000000100 in binary)
if( (Number & 0x0004) != 0 )
{
// third bit is set
}

// test bit 15 (use mask value 0x8000, which is
// 1000000000000000 in binary)
if( (Number & 0x8000) != 0 )
{
// top bit is set
}

// or as a short-hand representation of the same thing:
// (since zero is interpreted as 'false')
if( Number & 0x8000 )
{
// top bit is set
}


which is exactly that the KEYDOWN macro is doing.

(The " ? 1 : 0 " part is not strictly necessary here. What it is doing is converting any true (nonzero) value to the value 1, which is pretty pointelss if you ask me unless you are comparing it with the value 1, and why you would want to do that I don't know...)

Hope that helps a little, though theres plenty more to learn about macros (several pitfalls and traps for the unwary... not all the code i have written here should be copied!)

[Edit - Fixed errors in example]




[edited by - Crazemanx on November 1, 2002 2:53:48 PM]

Share this post


Link to post
Share on other sites
ok, so i have a SHORT (2bytes)...if i break up the two bytes i have...

SHORT KeyState;
00000001 00000000
|byte1| |byte0|

Byte1 contains the information of if the key is down and Byte0 contains the last state of the key.

so to test byte 1 I say...

BYTE TestValue = KeyState & 0x8000;

now TestValue is the value of the high bit in KeyState. (?)

and i can say...

if(TestValue)
{
//key is down
}

or, to make it simplier,

if(GetAsyncKeyState(VK_RETURN) & 0x8000)
{
//return is down
}

i wanted to explain that just to make sure i got it right...did i?

thanks alot man.

EDIT: byte order



[edited by - MattS423 on November 1, 2002 3:45:01 PM]

Share this post


Link to post
Share on other sites
quote:

BYTE TestValue = KeyState & 0x8000;

now TestValue is the value of the high bit in KeyState. (?)


Yes, TestValue can be either 0x8000, if the high bit in KeyState is 1, or zero of the high bit in KeyState is zero.

quote:

if(GetAsyncKeyState(VK_RETURN) & 0x8000)
{
//return is down
}


Yeah, that''s exactly right. Sorry about the delay in replying.

(P.S. here''s a handy tip, make a macro like this:

#define BIT(n) (1<<(n))

then BIT(15) is (1<<(15)) which is (in binary) 100000000000000 which is 0x8000, and so on.

There is no problem with efficiency, as the compiler will perform the left shift and compile the actual value into the code directly.)

Share this post


Link to post
Share on other sites