开发者

Breaking up a LPARAM variable & looking at groups of bits

I know that a LPARAM variable has certain bits set(inside it) that identify information such as long key presses & etc. when I receive a WM_KEYDOWN event.

So I am trying to break up a LPARAM variable & look at groups of individual bit values & groups of bits & that value(for eg looking at the 16th to the 24th bit & the value from 开发者_JAVA技巧that).

My Problem: I dont know how to look at individual bits & groups of bits? How do I break up the LPARAM variable & look at bit values (printing it out in binary, hex & decimal).

I have this so far, but working at the bit level confuses me alot, so I am unsure if I am really looking at the 24th, 25th & 16th bit value in decimal & etc.

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

    switch(msg)
    {
        case WM_KEYDOWN:
        {
            // I know that a LPARAM variable is a 32 bit(or is it byte?) long variable. How would I look at the
            // 16th bit value? How would I look that the value from the 16th to the 24th bit?
            printf("A: %d, %d, %d\n", lParam >> 24, lParam >> 25, lParam >> 16 );
        }
        break;


In general, you use bitwise-AND to check if a certain bit is set:

unsigned int flags;  // some flags

if (flags & 0x01) { } // bit 0 is set
if (flags & 0x02) { } // bit 1 is set
if (flags & 0x04) { } // bit 2 is set
...
if (flags & (1U << n)) { } // bit n is set

However, don't rely on the physical bit values. Instead, the API defines USEFUL_CONSTANTS that describe the meaning of the flags:

LPARAM flags = ApiFunction();
if (flags & USEFUL_CONSTANT) { } // check if the flag is set

Check the API documentation of the relevant message to find out which values are defined.

Update: I see that in your case you might actually want values rather than just flags. So, to get the value of the lowest 16 bits, you just bitwise-AND the value with the corresponding bitmask: unsigned int repeat_count = flags & 0xFFFF; Note that 0xFFFF is 1111111111111111 in binary.


A much easier way is to declare your own structure.

// information about key
union KeyInfo
{
  // LPARAM
  LPARAM lParam;

  // bit-field
  struct Bits {
    WORD nRepeatCount: 16;
    BYTE nScanCode : 8;
    BYTE nExtended : 1;
    BYTE nReserved : 4;
    BYTE nContext : 1;
    BYTE nPrevious : 1;
    BYTE nTransition : 1;
  };
};

That said, it's still a good idea to learn bit-arithmetic & as someone in the thread said there is a wealth of resources for this on the internet that can be found via Google.

EDIT: See this link which basically shows how to do what I just did.


LPARAM can hold a pointer value, this is important for 64-bit compatibility.

To examine the nth bit (0 is least significant):

if (lParam & (1 << n)) { /*bit set*/ } else { /* bit not set*/ }

To extract it as either 0 or 1:

(lParam >> n) & 1

To extract X bits from position Y:

(lParam >> Y) & ((1<<X)-1)

This works by first shifting the bytes down to the least significant places and creates a X bit wide mask to mask them out.


The most practical thing here is to use Google. For example if you google, "case WM_KEYDOWN" you will find sample code that shows how to check the different values embedded in LPARAM and WPARAM. Because each message has its own WPARAM and LPARAM handling, it's usually easiest to just look how other people are doing it, and copy. MSDN also has examples. Bit set manipulation is a whole set of arithmetic, so it's not practical to explain it all here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜