Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何在应用程序中的F1上应用键盘挂钩_Delphi_Local_Delphi 10.1 Berlin_Keyboard Hook - Fatal编程技术网

Delphi 如何在应用程序中的F1上应用键盘挂钩

Delphi 如何在应用程序中的F1上应用键盘挂钩,delphi,local,delphi-10.1-berlin,keyboard-hook,Delphi,Local,Delphi 10.1 Berlin,Keyboard Hook,对于我们的应用程序,我们创建了一个在线帮助,客户可以在其中查找有关我们应用程序的信息。他们可以在菜单中实现这一点,但我也希望在我们的应用程序中按F1键(因为这主要用于在其他应用程序中提供帮助) 我尝试使用RegisterHotKey函数,但结果是,它在系统范围内注册热键。我只希望它在您进入我们的应用程序时打开我们的在线帮助 所以我试着设置一个键盘挂钩,但这似乎也适用于整个系统。有没有办法确保在应用程序中按F1键可以打开它,但在应用程序未聚焦时不能打开 编码我尝试的内容: procedure WM

对于我们的应用程序,我们创建了一个在线帮助,客户可以在其中查找有关我们应用程序的信息。他们可以在菜单中实现这一点,但我也希望在我们的应用程序中按F1键(因为这主要用于在其他应用程序中提供帮助)

我尝试使用RegisterHotKey函数,但结果是,它在系统范围内注册热键。我只希望它在您进入我们的应用程序时打开我们的在线帮助

所以我试着设置一个键盘挂钩,但这似乎也适用于整个系统。有没有办法确保在应用程序中按F1键可以打开它,但在应用程序未聚焦时不能打开

编码我尝试的内容:

procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;

procedure TZZ_Main_Form.WMHotKey(var Msg: TWMHotKey);
begin
  if Msg.HotKey = HotKeyIDF1 then btOnlineHelpClick(nil);
end;
在FormCreate和FormDestroy中:

RegisterHotKey(Handle, HotKeyIDF1, 0, VK_F1);
UnRegisterHotKey(Handle, HotKeyIDF1);
关于键盘挂钩,我尝试了:

  hkHook := SetWindowsHookEx(WH_KEYBOARD,@KeyboardProc,hInstance,GetCurrentThreadID());

function KeyboardProc(Code, wParam, lParam: Integer): Integer;
var
  url: String;
  ShellInfo: TShellExecuteInfo;
begin
  try
    case wParam of
      VK_F1:
      begin
        url := 'ourOnlineHelpLink'
        if url <> '' then
        begin
          FillChar( ShellInfo, SizeOf( TShellExecuteInfo ), 0 );
          ShellInfo.cbSize := SizeOf( TShellExecuteInfo );
          ShellInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_NO_UI or
                         SEE_MASK_FLAG_DDEWAIT;
          ShellInfo.Wnd := HWnd_Desktop;
          ShellInfo.lpVerb := 'OPEN';
          ShellInfo.lpFile := PChar( url );
          ShellInfo.lpParameters := nil;
          ShellInfo.lpDirectory := nil;
          ShellInfo.nShow := sw_ShowNormal;

          ShellExecuteEx( @ShellInfo );
        end;
      end;
    end;
  finally
     Result := -1;
  end;
end;
hkHook:=setWindowshookx(WH_键盘,@KeyboardProc,hInstance,GetCurrentThreadID());
函数KeyboardProc(Code,wParam,lParam:Integer):Integer;
变量
url:String;
ShellInfo:TShellExecuteInfo;
开始
尝试
案例wParam
VK_F1:
开始
url:=“我们的在线帮助链接”
如果url为“”,则
开始
FillChar(ShellInfo,SizeOf(TShellExecuteInfo),0);
ShellInfo.cbSize:=SizeOf(TShellExecuteInfo);
ShellInfo.fMask:=请参阅\u MASK\u NOCLOSEPROCESS或参阅\u MASK\u FLAG\u NO\u UI或
请参阅\u掩码\u标志\u等待;
ShellInfo.Wnd:=HWnd_桌面;
ShellInfo.lpVerb:=“打开”;
ShellInfo.lpFile:=PChar(url);
ShellInfo.lpParameters:=nil;
ShellInfo.lpDirectory:=nil;
ShellInfo.nShow:=sw_ShowNormal;
ShellExecuteEx(@ShellInfo);
结束;
结束;
结束;
最后
结果:=-1;
结束;
结束;

如果您想向应用程序显示联机帮助,则更愿意使用现有的帮助支持,使用Ondrej Kelle在其评论中建议的事件

使用现有的帮助系统还提供了另一个优势。也就是说,对于每个控件,您可以为
HelpContext
HelpKeyword
设置特定值,这意味着您不必打开联机帮助起始页,而是可以导航到相关的帮助页,从而使您的应用程序用户更容易使用提供的帮助系统


顺便说一句,如果您不想使用HTMLHelp systey通过OnHelp事件获得在线帮助,您仍然可以轻松实现自己的系统来显示帮助。

如果您想向应用程序显示在线帮助,那么您宁愿使用现有的帮助支持,使用Ondrej Kelle在其评论中建议的事件

使用现有的帮助系统还提供了另一个优势。也就是说,对于每个控件,您可以为
HelpContext
HelpKeyword
设置特定值,这意味着您不必打开联机帮助起始页,而是可以导航到相关的帮助页,从而使您的应用程序用户更容易使用提供的帮助系统

顺便说一句,如果您不想使用HTMLHelp systey通过OnHelp事件获得在线帮助,您仍然可以轻松实现自己的系统来显示帮助。

您可以使用
TApplicationEvents.OnHelp在F1应用程序范围内截获帮助

将组件放到主窗体上,或者放到在主窗体之前创建的数据模块中。双击事件选项卡上的
OnHelp
事件,并添加类似于以下内容的代码(参数类型在Delphi 2007之后发生了更改,因此我已经包含了对这两种类型的支持):

您可以使用
TApplicationEvents.OnHelp
在整个F1应用程序范围内拦截该事件

将组件放到主窗体上,或者放到在主窗体之前创建的数据模块中。双击事件选项卡上的
OnHelp
事件,并添加类似于以下内容的代码(参数类型在Delphi 2007之后发生了更改,因此我已经包含了对这两种类型的支持):


您是否已经尝试使用窗体的OnKeyDown事件并启用KeyPreview?已经有一个事件您可以使用…在我的主窗体上尝试了它,只要主窗体有焦点,这似乎就可以工作。一旦我打开另一个表单,它就会停止工作。我需要的东西,适用于它,而其他形式可以是积极的。谢谢你的建议@AncaronDid您是否已经尝试使用窗体的OnKeyDown事件并启用KeyPreview?已经有事件可以使用…在我的主窗体上尝试过,只要主窗体有焦点,这似乎就可以工作。一旦我打开另一个表单,它就会停止工作。我需要的东西,适用于它,而其他形式可以是积极的。谢谢你的建议@Ancaron这似乎是一个更好的解决方案,我将ApplicationEvents组件放到了我的主窗体上,并设置了OnHelp函数,但当我启动应用程序并按F1时,它似乎没有被触发。我是否也需要在某个地方初始化它?我似乎发现了问题;有人将Application.onHelp设置为一个函数,该函数将CallHelp设置为false,因此不会触发正确的事件。现在我已经将它设置为我自己的事件,它似乎在任何地方都能工作。这似乎是一个更好的解决方案,我将ApplicationEvents组件放到了我的主窗体上,并设置了OnHelp函数,但当我启动应用程序并按F1时,它似乎不会被触发。我是否也需要在某个地方初始化它?我似乎发现了问题;有人将Application.onHelp设置为一个函数,该函数将CallHelp设置为false,因此不会触发正确的事件。现在我已经将它设置为我自己的活动,它似乎在任何地方都能工作。这也将非常令人惊讶,这取决于你在应用程序中的位置,在线帮助将为你查找相关章节。这也将非常令人惊讶,取决于你在哪里
// Delphi 2007 and earlier
{$IFDEF VER185}
function TMainForm.ApplicationEvents1Help(Command: Word; Data: Integer;
  var CallHelp: Boolean): Boolean;
begin
  CallHelp := False;
  // Call your own procedure to implement help as you'd like
  Result := True;
end;
{$ELSE Greater than D2007}
function TMainForm.ApplicationEvents1Help(Command: Word; Data: NativeInt;
  var CallHelp: Boolean): Boolean;
begin
  CallHelp := False;
  // Call your own procedure to implement help as you'd like
  Result := True;
end;
{$ENDIF}