从模态窗口打开的帮助文件没有响应

TJ *_*her 8 delphi helpfile delphi-xe2

使用Delphi XE2,Win64.

所以我有一个包含多种表单的大型应用程序,如果我从主窗体打开帮助文件并打开一个模态窗口然后点击F1以触发模态窗口上的上下文相关帮助,帮助文件窗口会显示正确的信息但是在关闭模态窗口之前,无法关闭帮助文件.如果我回到应用程序直到模态窗口关闭,我甚至无法让帮助文件再次获得焦点.

调用这个确切的从旧版本我们的应用程序(用Delphi 6个内置)的同一帮助文件坐在同一个文件夹中的新版本(与德尔福XE2建)的帮助文件时会显示F1键从模态窗口击中,是响应,可以像我期望的那样关闭.

帮助文件是.chm类型文件.

总结一下.

启动应用程序通过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.
Run Code Online (Sandbox Code Playgroud)

这是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.
Run Code Online (Sandbox Code Playgroud)

我将两个表单上的helpcontext属性设置为我的帮助文件中的两个有效上下文.

运行应用程序 - F1打开帮助文件命中按钮,以便创建Form2并显示F1以调用帮助文件在关闭Form2之前无法关闭帮助文件.

希望这可以帮助. - TJ

Dav*_*nan 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;
Run Code Online (Sandbox Code Playgroud)

把它放在一个类中并Application.OnHelp在启动时分配它:

Application.OnHelp := THelpWindowManager.ApplicationHelp;
Run Code Online (Sandbox Code Playgroud)

我刚刚在琐碎的两个表单应用程序上测试了它,它运行良好.在实际代码中,您可能希望修饰它.例如,我的实际代码更复杂.它在用户设置中存储关闭时帮助窗口的位置和窗口状态.然后再次显示时,恢复该位置和窗口状态.这样帮助窗口就会记住它在屏幕上的最后位置.


感谢@Sertac在下面的评论中详细说明了细节.总结一下,HtmlHelpViewer代码出错的地方:

  1. 它使得HH_INITIALIZE在帮助系统启动时发送命令.
  2. 文档中所述,这将HTML帮助配置为在与调用应用程序相同的线程上运行,而不是在辅助线程上运行.
  3. 当你调用ShowModal,调用DisableTaskWindows它禁用调用线程窗口.
  4. 由于帮助查看器窗口是由应用程序的主线程创建的(因为该HH_INITIALIZE命令),因此它被禁用.

这就是为什么当Delphi模态形式处于活动状态时,您无法与预先存在的帮助窗口进行交互.