DarosRT10
DarosRT10

Reputation: 31

Reading bits from the bin value

What is the order one has to read the bits from the bin value? Having for e.g. this official MS doc site regarding the lParam of the WM_CHAR message, they explain what bits have what meaning. Taking the bits 16-23 for the scan code value should I read the bits from right to left or vice versa?

Upvotes: 0

Views: 132

Answers (2)

0___________
0___________

Reputation: 68034

two ways:

UINT bitsxtractBits(UINT val, int startBit, int nbits)
{
    UINT mask = ((UINT)1 << nbits) - 1;

    return (val & mask) >> startBit;
}

//note it will not work if you want to extract all bits (in this case 32). 
//but in this case you do not need to extract them :)

and the usage to extract your bits:

bitsxtractBits(message, 16, 8)

or

union WM_CHAR_message
{
    struct 
    {
        UINT    repatCount : 16;
        UINT    scanCode   : 8;
        UINT    : 4;
        UINT    contextCode : 1;
        UINT    previousState : 1;
        UINT    transitionState : 1;
    };
    UINT  raw;
};

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    union WM_CHAR_message msgu;
    //C++ safe
    memcpy(&msgu, &message, sizeof(msgu));  // will be optimized to the store instruction only
    switch (message)
    {
   
    // ...

    case WM_CHAR:
        switch(msgu.scanCode)
        {
            //....
        }
        OnKeyPress(wParam);
        break;

    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

Upvotes: 1

Ted Lyngmo
Ted Lyngmo

Reputation: 118077

The page you linked to uses LSB 0 bit numbering so you can extract bits 16-23 with

lParam & 0b00000000111111110000000000000000U
//         |       |      |               |
// bit    31      23     16               0
//        MSB                            LSB

Note: The 0b prefix for binary numbers requires C++14. In C it's only available as an extension in some implementations.

You may also want to shift down the result with

(lParam & 0b00000000111111110000000000000000U) >> 16U

or simpler

(lParam >> 16U) & 0b11111111U //  or  (lParam >> 16U) & 0xFFU

Upvotes: 2

Related Questions