0

我从 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

4 回答 4

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)

逻辑 and意味着对于每个位,如果两个值都为 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  

所以记录一下:逻辑与运算的结果是一个数字,而不是真/假。由于您希望结果包含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 相比不会使您的代码不言自明

于 2011-08-09T22:36:48.973 回答
1

尝试

return (returnValue & KBDI_KEYBOARD_ALPHA_NUM) != 0;

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

于 2011-08-09T22:08:36.320 回答
1

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

return (returnValue & KBDI_KEYBOARD_ALPHA_NUM) != 0;
于 2011-08-09T22:08:36.637 回答
0

基本上你需要检查是否设置了第四位,所以只需使用按位与运算:

bool IsAbc(int key)
{
  return 0 != (0x08 & key);
}
于 2011-08-09T22:10:26.820 回答