This question may have already been answered but I've been unable to find the proper response. I'm trying to turn toggle a debug switch when the F12 key is pressed in a form. I'm unable to use the onkeydown event since I would have to setup a separate function for each field along with the form. So I've researched and found the SetWindowsHookEx function to set a keyboard hook. This working well except I'm getting two indications the F12 key has been press each time it is pressed:
2014/05/21 14:16:43.334
Code: 0
Key: 123
KeyStroke: 5767169
KeyStroke to Hex: 00580001
2014/05/21 14:16:43.446
Code: 0
Key: 123
KeyStroke: -1067974655
KeyStroke to Hex: C0580001 Note: this should be the keystroke that reflects KEYDOWN
I see the Keystroke is a possible method to check for keydown (WM_KEYDOWN $0100). My question is how do I test Keystroke for WM_KEYDOWN?
Here is my callback function:
function KeyboardHookProc(Code: Integer; Key: Word; KeyStroke: LongInt) : LongInt;
begin
Result := 0;
if Code = HC_NOREMOVE then exit;
Result := CallNextHookEx(FkbHook, Code,Key,KeyStroke);
if Code < 0 then exit;
{
WM_KEYDOWN
}
if (KeyStroke and WM_KEYDOWN) = 0 then { this is where I need to test but this doesn't work! }
begin
if Code = HC_ACTION then
begin
case Key of
vk_F12: begin
TKPMF.Memo1.Lines.Add(FormatDatetime('yyyy/mm/dd hh:nn:ss.zzz',now));
TKPMF.Memo1.Lines.Add('Code: ' + IntToStr(Code));
TKPMF.Memo1.Lines.Add('Key: ' + IntToStr(Key));
TKPMF.Memo1.Lines.Add('KeyStroke: ' + IntToStr(KeyStroke));
TKPMF.Memo1.Lines.Add('KeyStroke to Hex: ' + LongToHex(KeyStroke));
end;
end; {case}
end;
end;
end;
You do not need to assign a different handler to each individual control's OnKeyDown
event. You can assign all of them to use the same single handler. If you enable the form's KeyPreview
property then you won't need to assign a handler to any of the control's at all, you can use the Form's OnKeyDown
event by itself. If you need to detect the key press when you have multiple forms open, you can use the TApplication.OnMessage
or TApplicationEvents.OnMessage
event instead. Either way, you do not need to use a keyboard hook via SetWindowsHooKEx()
at all.
The reason your hook is not working is because WM_KEYDOWN
is a window message, not a Keystroke flag. Read the documentation. The Keystroke of the two messages you showed differ only in bits 30 (previous key state) and 31 (transition state).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With