为什么我的键盘挂钩会多次收到相同的按键和按键事件?

时间:2012-03-26 02:42:22

标签: delphi hook keyboard-events

my previous question中,我报告说在扫描条形码时,键盘挂钩报告了两次。

我把它放到了关键时刻。重点活动并收到了很好的建议。

仔细观察后,我发现每个数字实际上都在报告四次!

这是一个粗略的“打印调试”。任何人都可以建议我可能做错了吗?你需要更多信息吗?我可以忽略每一秒输入,但是......好吧!我宁愿了解正在发生的事情。

这是我得到的单个数字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 个答案:

答案 0 :(得分:9)

您的问题与评估Code参数值的方式有关。 有关KeyboardProc callback function州的文档:

  

<强> HC_NOREMOVE                wParam和lParam参数包含有关击键消息的信息,而键击消息尚未包含   从消息队列中删除。 (一个名为PeekMessage的应用程序   function,指定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;