如何在应用程序中的 F1 上应用键盘挂钩
How to apply a keyboardhook on F1 within the application
对于我们的应用程序,我们创建了一个在线帮助,客户可以在其中查找有关我们应用程序的信息。他们可以在菜单中找到它,但我也想通过在我们的应用程序中的任何位置按 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;
如果您想向您的应用程序显示在线帮助,那么您宁愿使用现有的帮助支持使用 OnHelp 事件,因为 Ondrej Kelle 已经在他的评论中推荐了。
使用现有的帮助系统还有另一个优势。那就是对于您的每个控件,您可以为 HelpContext
和 HelpKeyword
设置特定值,这意味着您可以导航到相关的帮助页面,而不是打开在线帮助起始页面,该页面使用提供的帮助系统对您的应用程序用户来说更容易。
顺便说一下,如果您不想使用 HTMLHelp 系统通过 OnHelp 事件获取在线帮助,您仍然可以轻松实现自己的系统来显示帮助。
您可以使用 TApplicationEvents.OnHelp
在应用程序范围内拦截 F1。
将组件拖放到主窗体上,或者拖放到主窗体之前创建的数据模块中。双击事件选项卡上的 OnHelp
事件,并添加类似于以下的代码(参数类型在 Delphi 2007 之后发生了变化,因此我已经包含了对两者的支持):
// 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}
对于我们的应用程序,我们创建了一个在线帮助,客户可以在其中查找有关我们应用程序的信息。他们可以在菜单中找到它,但我也想通过在我们的应用程序中的任何位置按 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;
如果您想向您的应用程序显示在线帮助,那么您宁愿使用现有的帮助支持使用 OnHelp 事件,因为 Ondrej Kelle 已经在他的评论中推荐了。
使用现有的帮助系统还有另一个优势。那就是对于您的每个控件,您可以为 HelpContext
和 HelpKeyword
设置特定值,这意味着您可以导航到相关的帮助页面,而不是打开在线帮助起始页面,该页面使用提供的帮助系统对您的应用程序用户来说更容易。
顺便说一下,如果您不想使用 HTMLHelp 系统通过 OnHelp 事件获取在线帮助,您仍然可以轻松实现自己的系统来显示帮助。
您可以使用 TApplicationEvents.OnHelp
在应用程序范围内拦截 F1。
将组件拖放到主窗体上,或者拖放到主窗体之前创建的数据模块中。双击事件选项卡上的 OnHelp
事件,并添加类似于以下的代码(参数类型在 Delphi 2007 之后发生了变化,因此我已经包含了对两者的支持):
// 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}