views:

389

answers:

3

How can a Win32 application respond to only the first WM_KEYDOWN notification? The MSDN docs claim bit 30 "Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is zero if the key is up." but bit 30 is always 0 in my WndProc.

case WM_KEYDOWN:
    // ToDo - stop multiple notifications for repeating keys
    printf("WM_KEYDOWN %i %i", wParam, lParam & 30);
 return 0;

Is lParam & 30 the wrong way to ask for this? Am I doing something else wrong?

+4  A: 

To get bit 30, you need this:

(lParam & 0x40000000)

An alternative would be to use bits 0-15 to get the repeat count:

int repeatCount = (lParam & 0xffff)

and only do anything if the repeat count is 0 (or possibly 1; I'm not sure whether the first message gets a repeat count of 0 or 1, and it's not clear from the documentation).

RichieHindle
This worked - thank you. My bit fiddling-fu is a little shaky. What exactly is 0x40000000?
Nick
That's a DWORD representing a bitmask consisting of bit 30 set and all other bits cleared.
sharptooth
You might want to read an introduction to hexadecimal, eg. http://www.learn-programming.za.net/articles_decbinhexoct.html It's not too hard, but not so trivial that I can explain it all here.
RichieHindle
+7  A: 

To test bit 30 don't AND with 30, instead AND with 1 << 30.

const bool isBitSet = lParam & (1 << 30);
sharptooth
Yep this works too - thanks
Nick
I actually think this reads better than the 0x4000000, so +1
Davy Landman
It probably does read better but it has to be computed every time (unless the compiler is optimizing this). 0x4000000 Will be faster.
kjfletch
VC++7 is optimizing it to a constant value.
sharptooth
@kjfletch those kind of micro optimizations are certainly not needed anymore.. Any simple compiler could optimize that..
Davy Landman
A: 

The problem with doing lParam & 30 is that, '30' over here is considered to be in decimal, which when converted to binary would '11110'. Hence you are not testing bit 30 but just getting the result for lparam & 11110.

Hope this helps in clarifying the problem a bit.

Pratik Bhatt