如何检查返回的位掩码值?

时间:2011-08-09 22:03:22

标签: c# bitmask bit-masks

我从C#调用此函数: GetKeyboardStatus()

查看文档,它说它返回一个掩码值。我的代码的目标是确定设备是否具有带字母数字字符的物理键盘。我已成功调用此函数,返回值为15.但由于我不理解位掩码,我不知道如何将其与0x0008值进行比较,根据文档“指示是否键盘硬件”有字母数字键。“我没有将此标记为Windows Mobile或Compact Framework问题,因为我认为您需要理解的所有内容都是位掩码和C#,我希望答案能够扩展我对如何使用位掩码的理解(虽然不是必需的)。这是我的代码。我认为唯一错误的部分是return语句:

        public static bool HasAlphaNumericKeys {
            get {
                const uint KBDI_KEYBOARD_ALPHA_NUM = 0x0008;
                uint returnValue = GetKeyboardStatus();
                return returnValue == KBDI_KEYBOARD_ALPHA_NUM;
            }
        }

        [DllImport("coredll")]
        private static extern uint GetKeyboardStatus();

感谢您尝试提供帮助,但我发现这不是确定是否存在带字母数字键的物理键盘的可靠方法。我尝试了2个设备,一个带键盘,一个没有,GetKeyboardStatus函数返回15,所以我甚至无法在答案中测试位掩码的解释。

4 个答案:

答案 0 :(得分:2)

如果你真的把它们写在一张纸上作为二进制值,那么按位操作会更容易理解

你15(十进制)是二进制1111(2 ^ 3 + 2 ^ 2 + 2 ^ 1 + 2 ^ 0)=(8 + 4 + 2 + 1)
8(十进制)是二进制1000(2 ^ 3 + 0 + 0 + 0)=(8 + 0 + 0 + 0)

逻辑和表示如果两个值均为1,则每个位的结果为1,否则为0

    In our case the (Y means both are 1 and N means one or both have a 0):
    1111
    1000
    ----
    YNNN

    Or in it's binary result
    1000  

所以对于记录:逻辑AND操作的结果是一个数字而不是true / false。 由于您希望结果具有 all 来自KBDI_KEYBOARD_ALPHA_NUM设置的位,我希望像这样检查

if ((returnValue & KBDI_KEYBOARD_ALPHA_NUM) == KBDI_KEYBOARD_ALPHA_NUM) { /* YES */ }

只有当我想要设置KBDI_KEYBOARD_ALPHA_NUM中的 任何 位时,才会将结果与!= 0进行比较。因为在这种情况下只涉及1位,所以两者都将起作用。但要说明不同之处:

const uint NEED_ALL_THESE_BITS = 0x0009;   // Binary: 1001
uint result = 3; // Binary: 0011;
((result & NEED_ALL_THESE_BITS) != 0) --> True
((result & NEED_ALL_THESE_BITS) == NEED_ALL_THESE_BITS) --> False

当你想要设置所有位时,比较!= 0不会使你的代码不言自明

答案 1 :(得分:1)

尝试

return (returnValue & KBDI_KEYBOARD_ALPHA_NUM) != 0;

如果设置了returnValue的第3位,则返回true,而不管returnValue中任何其他位的值如何。

答案 2 :(得分:1)

我相信按位运算符是你想要的,特别是按位 - 和(&)。按位AND查看两个操作数的每个位,如果两个位都为“1”则返回“1”,否则返回“0”。因此,如果您使用具有特定标志值的位掩码并获得非零结果,则您知道位掩码包含该标志。

return (returnValue & KBDI_KEYBOARD_ALPHA_NUM) != 0;

答案 3 :(得分:0)

基本上你需要检查第四位是否设置,所以只需使用按位AND操作:

bool IsAbc(int key)
{
  return 0 != (0x08 & key);
}