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.
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;
来源:https://stackoverflow.com/questions/9865990/why-does-my-keyboard-hook-receive-the-same-key-up-and-key-down-events-multiple-t