【问题标题】:Testing whether specific bits are set in a DWORD flag测试是否在 DWORD 标志中设置了特定位
【发布时间】:2011-08-13 10:09:36
【问题描述】:

我有一个 DWORD 变量,我想测试其中是否设置了特定位。我的代码如下,但我不确定我是否从 win32 数据类型 KBDLLHOOKSTRUCT 传输位我的 lparam 数据类型正确吗?

请参阅记录 DWORD 标志变量的 MSDN:http://msdn.microsoft.com/en-us/library/ms644967(v=vs.85).aspx

union KeyState 
{
    LPARAM lparam;      

    struct     
    {         
        unsigned nRepeatCount : 16;         
        unsigned nScanCode    : 8;         
        unsigned nExtended    : 1;         
        unsigned nReserved    : 4;         
        unsigned nContext     : 1;         
        unsigned nPrev        : 1;         
        unsigned nTrans       : 1;     
    }; 
}; 


KBDLLHOOKSTRUCT keyInfo = *((KBDLLHOOKSTRUCT*)lParam);
KeyState myParam;
myParam.nRepeatCount    = 1;
myParam.nScanCode       = keyInfo.scanCode;
myParam.nExtended       = keyInfo.flags && LLKHF_EXTENDED; // maybe it should be keyInfo.flags & LLKHF_EXTENDED or keyInfo.flags >> LLKHF_EXTENDED
myParam.nReserved       = 0;        
myParam.nContext        = keyInfo.flags && LLKHF_ALTDOWN;     
myParam.nPrev           = 0; // can store the last key pressed as virtual key/code, then check against this one, if its the same then set this to 1 else do 0   
myParam.nTrans          = keyInfo.flags && LLKHF_UP;


// Or maybe I shd do this to transfer bits...
myParam.nRepeatCount    = 1;
myParam.nScanCode       = keyInfo.scanCode;
myParam.nExtended       = keyInfo.flags & 0x01;
myParam.nReserved       = (keyInfo.flags >> 0x01) & (1<<3)-1;      
myParam.nContext        = keyInfo.flags & 0x05;     
myParam.nPrev           = 0;       // can store the last key pressed as virtual key/code, then check against this one, if its the same then set this to 1 else do 0   
myParam.nTrans          = keyInfo.flags & 0x07;

【问题讨论】:

  • 对于DWORD和位,简单的位操作就足够了uint bit_test(x,bitnum){ return x &amp; (1&lt;&lt;bitnum)}

标签: c++ winapi bit-manipulation


【解决方案1】:

而不是

myParam.nExtended = keyInfo.flags && LLKHF_EXTENDED

你需要

myParam.nExtended = (keyInfo.flags & LLKHF_EXTENDED) != 0;

它是&amp; 而不是&amp;&amp;,因为您需要位与而不是逻辑与!=0 确保答案是 0 或 1(而不是 0 或其他非零值),因此它可以在您的一位位域中表示。

【讨论】:

    【解决方案2】:
    CheckBits(DWORD var, DWORD mask)
    {
        DWORD setbits=var&mask; //Find all bits are set
        DWORD diffbits=setbits^mask; //Find all set bits that differ from mask
        return diffbits!=0; //Retrun True if all specific bits in variable are set
    }
    

    【讨论】:

    【解决方案3】:

    如果你想合并两个位,你会使用 | (bitwise OR) 运算符:

    myParam.nExtended = keyInfo.flags | LLKHF_EXTENDED;

    myParam.nExtended = keyInfo.flags | 0x01;

    要检查是否设置了位,您可以使用 &amp;按位与)运算符:

    if(myParam.nExtended &amp; LLKHF_EXTENDED) ...

    【讨论】:

    • 不使用位域,只需使用 myParam.nExtended = 1;此答案中的此代码应仅用于分配 lparam。不是 OP 所要求的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-15
    相关资源
    最近更新 更多