Почему мой хук клавиатуры получает несколько раз одни и те же события нажатия клавиш вверх и вниз? - PullRequest
5 голосов
/ 26 марта 2012

В моем предыдущем вопросе я сообщил, что при сканировании штрих-кода хук клавиатуры сообщал обо всем дважды.

Я записал это на ключевые события и получил хороший совет.

При более внимательном рассмотрении я обнаружил, что каждая цифра действительно сообщается ЧЕТЫРЕ раза!

Вот грубая «отладка с помощью печати». Кто-нибудь может подсказать, что я могу делать не так? Вам нужно больше информации? Я мог бы просто игнорировать каждый второй ввод, но ... блин! Я бы лучше понял, что происходит.

Вот что я получил за одну цифру 2

---------
LongParam = 196609 |  Word = 50 | 2
LongParam and $80000000 = 0
LongParam and $40000000 = 0
---------
LongParam = 196609 |  Word = 50 | 2
LongParam and $80000000 = 0
LongParam and $40000000 = 0
---------
LongParam = -1073545215 |  Word = 50 | 2
LongParam and $80000000 = 2147483648
LongParam and $40000000 = 1073741824
---------
LongParam = -1073545215 |  Word = 50 | 2
LongParam and $80000000 = 2147483648
LongParam and $40000000 = 1073741824

Обновление: вот мой код

function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
begin
   if Code < 0 then  // http://msdn.microsoft.com/enus/library/windows/desktop/ms644984%28v=vs.85%29.aspx
   begin
      Result := CallNextHookEx(KBHook, Code, WordParam, LongParam);
      Exit;
   end;

MainForm.Memo1.Lines.Add('---------');
MainForm.Memo1.Lines.Add('LongParam = ' + IntToStr(LongParam) +  ' |  Word = ' +         IntToStr(Ord(WordParam)) + ' | ' + Char(WordParam));
MainForm.Memo1.Lines.Add('LongParam and $80000000 = ' + IntToStr(LongParam and $80000000));
MainForm.Memo1.Lines.Add('LongParam and $40000000 = ' + IntToStr(LongParam and $40000000));

   if ((LongParam and $80000000) <> $80000000)  (* not key up *)
   or ((LongParam and $40000000) <> $40000000)  (* key was not previously down *)
   then
   begin
      Result := CallNextHookEx(KBHook, Code, WordParam, LongParam);
      Exit;
   end;

   if MainForm.ScanningChemical = False then
   begin
      Result := CallNextHookEx(KBHook, Code, WordParam, LongParam);
      Exit;
   end;

На данный момент у меня есть цифра штрих-кода. Но эти строки были добавлены ранее здесь.

1 Ответ

9 голосов
/ 26 марта 2012

Ваша проблема связана с тем, как вы оцениваете значение параметра Code. Документация о KeyboardProc callback function гласит:

HC_NOREMOVE Параметры wParam и lParam содержат информацию о сообщении о нажатии клавиши, и сообщение о нажатии клавиши не было удален из очереди сообщений. (Приложение под названием PeekMessage функция, указывающая флаг PM_NOREMOVE.)

Чтобы устранить проблему, просто замените этот код

   if Code < 0 then  
   begin
      Result := CallNextHookEx(KBHook, Code, WordParam, LongParam);
      Exit;
   end;

С этим

   if (Code < 0) or (Code = HC_NOREMOVE ) then
   begin
      Result := CallNextHookEx(KBHook, Code, wparam, lparam);
      Exit;
   end;
...