所以我有一个包含多种形式的大型应用程序,如果我打开主窗体中的帮助文件并打开一个模态窗口然后点击F1以触发模态窗口上的上下文相关帮助,帮助文件窗口会显示正确的信息但是在关闭模态窗口之前,无法关闭帮助文件.如果我回到应用程序直到模态窗口关闭,我甚至无法让帮助文件再次获得焦点.
从旧版本的应用程序(使用Delphi 6构建)调用与新版本(使用Delphi XE2构建)相同的文件夹中的这个完全相同的帮助文件,当从模态窗口命中F1键时显示帮助文件响应,可以像我期望的那样关闭.
总结一下.
启动程序
通过F1打开帮助文件
跳转到应用程序并在应用程序中打开模态窗口
点击F1,从模态窗口启动帮助
在我跳回我的应用程序并关闭模态窗口之前,无法关闭帮助文件窗口.
有没有人知道为什么会这样?
我搜索过互联网,但没有发现任何类似的问题.
我们很难过.
干杯
TJ
– – 编辑 – –
下面是一个示例两个表单应用程序的代码,它也表现出这种行为.
program Project1; uses Vcl.Forms,HTMLHelpViewer,Unit1 in 'Unit1.pas' {Form1},Unit2 in 'Unit2.pas' {Form2}; {$R *.res} begin Application.Initialize; Application.HelpFile := 'C:\helpfile.chm'; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1,Form1); Application.Run; end.
这是Form1代码:
unit Unit1; interface uses Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} uses Unit2; procedure TForm1.Button1Click(Sender: TObject); begin Form2 := TForm2.Create(Application); try Form2.ShowModal; finally Form2.Free; end; end; end.
我将两个表单上的helpcontext属性设置为我的帮助文件中的两个有效上下文.
运行应用程序 – F1以打开帮助文件
点击按钮,创建并显示Form2
F1调用帮助文件
在关闭Form2之前无法关闭帮助文件.
希望这可以帮助. – TJ
解决方法
我个人不使用HtmlHelpViewer,因为它不起作用.我为TApplication.OnHelp实现了一个处理程序.它看起来像这样:
class function THelpWindowManager.ApplicationHelp(Command: Word; Data: THelpEventData; var CallHelp: Boolean): Boolean; begin CallHelp := False; Result := True; //argh,WinHelp commands case Command of HELP_CONTEXT,HELP_CONTEXTPOPUP: HtmlHelp(GetDesktopWindow,Application.HelpFile,HH_HELP_CONTEXT,Data); end; end;
将它放在一个类中并在启动时将其分配给Application.OnHelp:
Application.OnHelp := THelpWindowManager.ApplicationHelp;
我刚刚在琐碎的两个表单应用程序上测试了它,它运行良好.在实际代码中,您可能希望修饰它.例如,我的实际代码更复杂.它在用户设置中存储关闭时帮助窗口的位置和窗口状态.然后再次显示时,恢复该位置和窗口状态.这样帮助窗口就会记住它最后在屏幕上的位置.
感谢@Sertac在下面的评论中挖掘出细节.总结这里HtmlHelpViewer代码出错的地方:
>它使得在帮助系统启动时发送HH_INITIALIZE
命令.
>如documentation中所述,这将HTML帮助配置为在与调用应用程序相同的线程上运行,而不是在辅助线程上运行.
>当您调用调用DisableTaskWindows的ShowModal时,它会禁用调用线程中的窗口.
>因为帮助查看器窗口是由应用程序的主线程创建的(因为HH_INITIALIZE命令),所以它被禁用.
这就是为什么在Delphi模态窗体处于活动状态时,您无法与预先存在的帮助窗口进行交互的原因.