使用Delphi编程实现键盘钩子来监测F12键的按下。

8

这个问题可能已经有了答案,但是我找不到适当的回应。 我正在尝试在表单中按下F12键时切换调试开关。 由于必须为每个字段以及表单设置单独的函数,所以我无法使用onkeydown事件。 因此,我进行了研究,并找到了SetWindowsHookEx函数来设置键盘钩子。 这个方法很好用,但每次按下F12键时我都会得到两个指示:

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

我看到按键输入是检测键盘按下的一种可能方法(WM_KEYDOWN $0100)。我的问题是如何测试按键输入是否为WM_KEYDOWN?

以下是我的回调函数:

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;

1
你使用的是哪个版本的Delphi?为什么不使用窗体的KeyPreview属性呢?https://dev59.com/umw15IYBdhLWcg3wmc4J - Frazz
2
在最坏的情况下,使用ApplicationEvents。无需挂钩您自己的应用程序。 - Sertac Akyuz
3
不确定为什么有人会在这里点踩。原帖提供了研究证据和示例代码。原帖的作者也是新手(声望=1),因此未能澄清 Delphi 版本是可以理解的。 - Argalatyr
3
这里没有downvote的理由。已经提供了足够的信息和努力(包括代码),而具体的Delphi版本是不相关的,因为KeyPreviewOnKeyDown事件自Delphi 1以来就存在,并且仍然存在于XE6中的VCL TForm中。 - Ken White
1个回答

12
您无需为每个控件的OnKeyDown事件分配不同的处理程序。您可以将它们全部分配给使用相同单个处理程序。如果启用了窗体的KeyPreview属性,则根本不需要为任何控件分配处理程序,只需使用窗体的OnKeyDown事件即可。如果您需要在打开多个窗体时检测按键,则可以使用TApplication.OnMessageTApplicationEvents.OnMessage事件。无论哪种方式,都无需通过SetWindowsHookEx()使用键盘钩子。

您的钩子不起作用的原因是WM_KEYDOWN是一个窗口消息,而不是按键标志。阅读文档。您显示的两条消息中的按键仅在位30(先前的键状态)和31(转换状态)中有所不同。


Remy,没错,像往常一样,我总是试图把事情搞得太复杂了。我总能指望你知道正确的答案。 - Rich R
1
当有人给出正确答案时,您应该点击按钮接受它(如果有多个答案,则仅适用于一个)。这样,回答者的声誉会略微提高,就像我们中的一些人在赞同您的问题时所做的那样,而答案则获得了绿色勾号,这有助于其他用户。 - MartynA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接