Как проверить возвращаемое значение битовой маски? - PullRequest
0 голосов
/ 10 августа 2011

Я вызываю эту функцию из 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 ]

2 голосов
/ 10 августа 2011

Побитовые операции становятся намного проще для понимания, если вы на самом деле пишете их на листе бумаги в виде двоичных значений

Вы 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)

A логический и означает, что для каждого бита, если оба значения равны 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 */ }

Я бы сравнил результат с! = 0только если я хочу, чтобы любой битов в KBDI_KEYBOARD_ALPHA_NUM был установлен.Поскольку в этом случае задействован только 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 голос
/ 10 августа 2011

Я считаю, что побитовые операторы - это то, что вам нужно, в частности, побитовый оператор AND (&). Побитовое И просматривает каждый бит двух операндов и возвращает «1», если оба бита равны «1», и «0» в противном случае. Так что, если вы И битовая маска с определенным значением флага и получили ненулевой результат, вы знаете, что битовая маска содержит флаг.

return (returnValue & KBDI_KEYBOARD_ALPHA_NUM) != 0;
1 голос
/ 10 августа 2011

Try

return (returnValue & KBDI_KEYBOARD_ALPHA_NUM) != 0;

Возвращает true, если установлен бит 3 returnValue, независимо от значений любых других битов в returnValue.

0 голосов
/ 10 августа 2011

Обычно вам нужно проверить, установлен ли четвертый бит, поэтому просто используйте побитовую операцию И:

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