Как использовать низкоуровневые 8-битные флаги в качестве условных выражений?

В моей клавиатуре каждое нажатие клавиши получает флаг, который указывает, была ли она введена или нет. http://msdn.microsoft.com/en-us/library/ms644967(VS.85).aspx

Я отогнал KBDLLHOOKSTRUCT от lParam. Я могу получить доступ к kbd.flags.XXX. Я просто не знаю, как преобразовать этот 8-битный флаг в if (injected) {... Тип условный, который я умею использовать.

Если бы один из вас, умный компьютерщик, помог бы мне, я был бы очень благодарен.

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        KBDLLHOOKSTRUCT kbd = new KBDLLHOOKSTRUCT();
        Marshal.PtrToStructure(lParam, kbd);

        //if (injected) {...

Ура!

5 ответов

Решение

Вам нужно поразрядно - и это с маской. Например, введенный бит - это бит 4. Это двоичный код 00010000, шестнадцатеричный 0x10. Таким образом, вы побитно - и это с 0x10, и посмотреть, если что-нибудь осталось:

bool isInjected = ((kbd.flags & 0x10) != 0);

(Конечно, согласно ответу Эндрю, было бы неплохо определить для этого константу LLKHF_INJECTED, а не включать шестнадцатеричное значение непосредственно в ваш код!)

.NET поддерживает это с помощью атрибута [Flags]:

[Flags]
enum KbdHookFlags {
  Extended = 0x01,
  Injected = 0x10,
  AltPressed = 0x20,
  Released = 0x80
}

Пример использования:

  KBDLLHOOKSTRUCT info = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
  if ((info.flags & KbdHookFlags.Released) == KbdHookFlags.Released) {
    // Key was released
    // etc..
  }

Используйте побитовый оператор AND, чтобы проверить, установлен ли соответствующий бит в переменной flags:

if (kbd.flags & LLKHF_INJECTED)
{
    ...
}

Вы должны проверить, что битовый флаг установлен. Легко сделать с помощью побитовых операций. В документации говорится, что для введенного флага используется бит четыре, бит 4 (или 5, если считать первый бит как 1) равен 16, так что вы можете сделать битовое И против флага.

if ((kbd.flags & 16) == 16)
{
    FireTorpedoes();
}

Вы можете узнать больше о побитовых операциях здесь:

Причина, по которой все говорят, использовать побитовое значение &, а затем сравнить с нулем или флагом:

  0111 1000        // kbd.flags 
& 0001 0000        // Injected
          =
  0001 0000        // (!= 0 or ==Injected)
Другие вопросы по тегам