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

В моей клавиатуре каждое нажатие клавиши получает флаг, который указывает, было ли оно введено или нет. 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 ]

11 голосов
/ 16 января 2010

.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..
  }
7 голосов
/ 16 января 2010

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

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

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

2 голосов
/ 16 января 2010

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

  0111 1000        // kbd.flags 
& 0001 0000        // Injected
          =
  0001 0000        // (!= 0 or ==Injected)
2 голосов
/ 16 января 2010

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

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

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

2 голосов
/ 16 января 2010

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

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