5

In my previous question, I reported that a keyboard hook was reporting everything twice when scanning a barcode.

I put that down to key down & key events and received good advice.

Having looked at it more closely I find that each digit is actually being report FOUR times!

Here's a crude "debug by print". Can anyone suggest what I might be doing wrong? Do you need more info? I could just ignore every second input, but ... yeuck! I would rather understand what is happening.

Here's what I got for a single digit 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

Update: here's my code

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;

At this point I have a bar code digit. But those memo lines were added before here.

Community
  • 1
  • 1
Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551

1 Answers1

10

Your issue is related to the way how you are evaluating the value of the Code param. The documentation about the KeyboardProc callback function states :

HC_NOREMOVE The wParam and lParam parameters contain information about a keystroke message, and the keystroke message has not been removed from the message queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)

To fix the problem just replace this code

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

With this

   if (Code < 0) or (Code = HC_NOREMOVE ) then
   begin
      Result := CallNextHookEx(KBHook, Code, wparam, lparam);
      Exit;
   end;
RRUZ
  • 134,889
  • 20
  • 356
  • 483