0

I started learning winapi using c++ language. I am trying to understand the lParam on WM_KEYDOWN message.

From the Microsoft documentation:

0-15: The repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.

16-23: The scan code. The value depends on the OEM.

24: Indicates whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.

25-28: Reserved; do not use.

29:The context code. The value is always 0 for a WM_KEYDOWN message.

30: 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.

31: The transition state. The value is always 0 for a WM_KEYDOWN message.

I am handling this message by this way:

case WM_KEYDOWN:
    cout << ((lParam & 0b11111111111111110000000000000000) >> 16) << ", ";
    cout << ((lParam & 0b00000000000000001111111100000000) >> 8) << ", ";
    cout << ((lParam & 0b00000000000000000000000010000000) >> 7) << ", ";
    cout << ((lParam & 0b00000000000000000000000000000100) >> 2) << ", ";
    cout << ((lParam & 0b00000000000000000000000000000010) >> 1) << ", ";
    cout << ((lParam & 0b00000000000000000000000000000001) >> 0) << endl;

And if I press "A" button on my keyboard I get ouput: 30, 0, 0, 0, 0, 1

If I hold "A" button I get muliple outputs:

16414, 0, 0, 0, 0, 1
16414, 0, 0, 0, 0, 1
16414, 0, 0, 0, 0, 1

If I press other letter button, I get same result but with other first number. (For example, for "B" button I get 48 as simple press, 49200 as holding)

How can I understand it?

Don2Quixote
  • 228
  • 2
  • 12

1 Answers1

6

I didn't test this, but your bit ordering appears to be reversed. According to MS Documentation, bits 0-15 are the LOW bits.

case WM_KEYDOWN:
    cout << ((lParam & 0b00000000000000001111111111111111) >> 0) << ", ";
    cout << ((lParam & 0b00000000111111110000000000000000) >> 16) << ", ";
    cout << ((lParam & 0b00000001000000000000000000000000) >> 24) << ", ";
    cout << ((lParam & 0b00100000000000000000000000000000) >> 29) << ", ";
    cout << ((lParam & 0b01000000000000000000000000000000) >> 30) << ", ";
    cout << ((lParam & 0b10000000000000000000000000000000) >> 31) << ", ";
ChrisMM
  • 8,448
  • 13
  • 29
  • 48
  • Doesn't 0b00000000000000001111111111111111 reserse in memory automatic? – Don2Quixote May 28 '20 at 15:02
  • 1
    @don If it does (e.g. on a little-endian architecture), then both the literal as well as the value passed through `lParam` get *"reversed"*. – IInspectable May 28 '20 at 15:49
  • @Don2Quixote, In little endian, the values are stored in memory in reverse (by byte). When loaded into the register to do these operations, they are loaded in the proper order. – ChrisMM May 28 '20 at 18:20
  • These are numbers, not bytes of memory being converted to a number. There is no "reverse" here. The numbers are just numbers. Endianness applies only when you store a number to memory and then read it back as bytes instead of as a number. – Raymond Chen May 29 '20 at 02:14