这个问题可能已经回答了,但是我一直找不到正确的答案。当试图以某种形式按下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

我看到按键是一种可能的方法来检查按键(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 - 键盘 Hook ,寻找带有delphi的F12,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23794124/

10-13 09:31