Как использовать низкоуровневые 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)