delphi - 用delphi寻找F12的键盘钩子(Hook)

标签 delphi setwindowshookex

这个问题可能已经得到解答,但我一直找不到正确的答案。我试图在表单中按下 F12 键时打开调试开关。我无法使用 onkeydown 事件,因为我必须为每个字段以及表单设置一个单独的函数。所以我研究并找到了SetWindowsHookEx函数来设置键盘钩子(Hook)。这工作得很好,除了每次按下 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

我发现击键是检查 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;

最佳答案

您不需要为每个控件的 OnKeyDown 事件分配不同的处理程序。您可以将它们全部指定为使用同一个处理程序。如果启用表单的 KeyPreview 属性,则根本不需要为任何控件分配处理程序,您可以单独使用表单的 OnKeyDown 事件。如果您需要在打开多个表单时检测按键,则可以使用 TApplication.OnMessageTApplicationEvents.OnMessage 事件。无论哪种方式,您根本不需要通过 SetWindowsHooKEx() 使用键盘 Hook 。

您的 Hook 不起作用的原因是因为 WM_KEYDOWN 是窗口消息,而不是击键标志。 Read the documentation 。您显示的两条消息的击键仅在位 30(先前的键状态)和 31(转换状态)方面有所不同。

关于delphi - 用delphi寻找F12的键盘钩子(Hook),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23794124/

相关文章:

delphi - 如何安装Delphi 10.4 Sydney命令行编译器(在Windows Server 2016上)?

file - 我如何存储可以在Delphi中运行时更改的文件路径

vb.net - 有没有VB应用程序迁移到delphi?

arrays - 将项目添加到数组的其他方法

c++ - 为什么 SetWindowsHookEx 不接受钩子(Hook)程序?

windows - Hook 特定进程的注册表访问的简单方法

mysql - 德尔福: Select into outfile using parameter

c++ - 确定消息发送到哪个窗口(SetWindowsHookEx & WH_KEYBOARD)

c++ - 来自非静态函数的 SetTimer

c# - SetWindowsHookEx 在 C# 中似乎对我不起作用(WH_KEYBOARD_LL,全局)