从 bin 值中读取位

Reading bits from the bin value

从 bin 值中读取位的顺序是什么?例如有this official MS doc 站点关于 lParamWM_CHAR 消息,他们解释了哪些位有什么含义。取16-23位为扫描码值,我应该从右向左读还是从右向左读?

您链接到的页面使用 LSB 0 bit numbering,因此您可以使用

提取第 16-23 位
lParam & 0b00000000111111110000000000000000U
//         |       |      |               |
// bit    31      23     16               0
//        MSB                            LSB

注意:二进制数的 0b 前缀需要 C++14。在 C 中,它仅在某些实现中作为扩展可用。

您可能还想将结果向下移动

(lParam & 0b00000000111111110000000000000000U) >> 16U

或更简单

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

两种方式:

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 :)

以及提取位的用法:

bitsxtractBits(message, 16, 8)

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;
}