用delphi查找F12的键盘挂钩

Posted

技术标签:

【中文标题】用delphi查找F12的键盘挂钩【英文标题】:Keyboard hook to look for F12 with delphi 【发布时间】:2014-05-21 21:28:00 【问题描述】:

这个问题可能已经得到解答,但我一直无法找到正确的答案。当在表单中按下 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

我看到 Keystroke 是检查 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;

【问题讨论】:

您使用的是什么版本的Delphi?为什么不使用表单的 KeyPreview? ***.com/questions/6509242/… 在最坏的情况下使用 ApplicationEvents。无需挂钩您自己的应用程序。 不知道为什么有人会在这里投反对票。 OP 展示了研究证据和示例代码。 OP 也是新的(rep=1),所以没有说明 Delphi 版本是情有可原的。 +1。没有理由在这里投反对票。提供了足够的信息和努力(包括代码),具体的 Delphi 版本无关紧要,因为 KeyPreviewOnKeyDown 事件自 Delphi 1 以来就存在,并且仍然存在于 XE6 的 VCL TForm 中。 【参考方案1】:

您不需要为每个单独控件的OnKeyDown 事件分配不同的处理程序。您可以分配所有这些以使用相同的单个处理程序。如果启用表单的KeyPreview 属性,则根本不需要为任何控件分配处理程序,您可以单独使用表单的OnKeyDown 事件。如果您需要在打开多个表单时检测按键,则可以使用TApplication.OnMessageTApplicationEvents.OnMessage 事件代替。无论哪种方式,您都不需要通过SetWindowsHooKEx() 使用键盘挂钩。

你的钩子不起作用的原因是因为WM_KEYDOWN 是一个窗口消息,而不是一个按键标志。 Read the documentation。您显示的两条消息的 Keystroke 仅在 30 位(先前的键状态)和 31 位(转换状态)不同。

【讨论】:

雷米,是的,就是这样,像往常一样,我试图让事情变得过于复杂。我总是可以指望你知道正确的答案。 当有人给你一个正确的答案时,你应该点击按钮接受它(如果有多个答案,只适用于一个)。这样一来,回答者的声望就会小幅提高,就像我们中的一些人对您的问题投赞成票时所做的那样,并且答案会获得一个绿色勾号,这有助于其他用户。

以上是关于用delphi查找F12的键盘挂钩的主要内容,如果未能解决你的问题,请参考以下文章

联想台式机键盘f1到f12不能用怎么解决

键盘上F1到F12都有什么用?如何用?

.NET 应用程序中未调用低级键盘挂钩

delphi中如何模拟最简单的键盘输入?

delphi7实现模拟键盘按键,比如按下v键,数字0,回车等

Delphi 软键盘