使用Delphi XE2,Win64。
所以我有一个包含多种表单的大型应用程序,如果我从主窗体中打开帮助文件并打开一个模态窗口然后点击F1以触发模态窗口上的上下文相关帮助,则帮助文件窗口显示正确的信息,但在我关闭模态窗口之前无法关闭帮助文件。如果我回到应用程序直到模态窗口关闭,我甚至无法让帮助文件再次获得焦点。
从旧版本的应用程序(使用Delphi 6构建)中调用此完全相同的帮助文件,该文件位于与新版本(使用Delphi XE2构建)相同的文件夹中,帮助文件显示在F1键从模态窗口中被击中并且响应迅速,可以像我期望的那样关闭。
帮助文件是.chm类型文件。
总结一下。
启动应用程序 通过F1打开帮助文件 在应用程序中跳转到应用程序并打开模态窗口 点击F1,从模态窗口启动帮助 在我跳回我的应用程序并关闭模态窗口之前,无法关闭帮助文件窗口。
有没有人知道为什么会这样?
我搜索了互联网,但没有发现任何类似的问题。
我们很难过。
干杯 TJ
---- ---- EDIT
以下是一个示例两个表单应用程序的代码,它也表现出这种行为。
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
答案 0 :(得分:9)
HtmlHelpViewer
这是一个严重的设计缺陷。并且很容易重现您描述的行为。为明确指出问题做得很好。这个问题同样困扰着32位和64位程序。
我个人不使用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
命令。ShowModal
调用DisableTaskWindows
时会调用调用线程中的窗口。HH_INITIALIZE
命令),因此它被禁用。这就是为什么当Delphi模态表单处于活动状态时,您无法与预先存在的帮助窗口进行交互。