将帮助文件链接到Delphi XE2应用程序 - 除主表单外,一切正常

Sen*_*ent 6 delphi chm mdi

我正在努力用我们的软件设置帮助文件.我为许多特定的表单/框架/控件添加了HelpContext数字,它们都可以正常工作.问题是主要表格根本没有提供任何帮助.对于所有这一切,我只使用F1尝试触发帮助.

我不是Delphi或帮助文件的专家,但我会发布我所做的和我看过的地方.

编辑:感谢一些帮助,我现在看到问题是由于主窗体是MDI父级.这仍然没有解决问题..它几乎对我来说似乎是一个错误,但我想这可能是出于某种原因故意.EndEdit中

我包括这个单元:HtmlHelpViewer用于查看器.在主窗体Create构造函数中,我添加了Application.Helpfile:='asdf.chm'.对于所有其他形式,我刚刚添加了上下文数字,它立即可用.我在主表单上尝试过,没有任何反应.所以我尝试添加一个Application.OnHelp事件但是这不会在主窗体上调用(并且它适用于所有其他帮助工作的窗体).

我能想到的最后一招是深入了解代码,看看发生了什么.我在Vcl.Forms中将TCustomForm.WMHelp作为拆分发生的地方.所述函数有这个循环:

if iContextType = HELPINFO_WINDOW then
begin
  Control := FindControl(hItemHandle);
  while (Control <> nil) and ( not ControlHasHelp(Control)) do
    Control := Control.Parent;
  if Control = nil then Exit;
  GetHelpInfo(Control, HType, ContextID, Keyword);
  Pt := Control.ClientToScreen(Point(0, 0));
end
Run Code Online (Sandbox Code Playgroud)

当主窗体调用时,帮助控件将为零,然后它将退出.其他任何事情都会好起来的.

我显然不知道为什么会这样.答案可能是非常基本的.任何想法,将不胜感激!

Dav*_*nan 6

根据您的评论,该WM_HELP消息将在您的MDI客户端窗口中定位.由于这不是VCL控件,因此它不响应WM_HELP消息.您可以通过拦截消息并要求主表单处理它来处理问题:

type
  TMainForm = class(TForm)
  protected
    procedure WMHelp(var Message: TWMHelp); message WM_HELP;
  end;
....
procedure TMainForm.WMHelp(var Message: TWMHelp);
begin
  if (Message.HelpInfo.iContextType=HELPINFO_WINDOW) 
  and (Message.HelpInfo.hItemHandle=ClientHandle) then 
    Message.HelpInfo.hItemHandle := Handle;
  inherited;
end;
Run Code Online (Sandbox Code Playgroud)

如果你想要更加防守,你可以像这样写:

  if (Message.HelpInfo.iContextType=HELPINFO_WINDOW) 
  and (FindControl(Message.HelpInfo.hItemHandle)=nil) then 
    Message.HelpInfo.hItemHandle := Handle;
Run Code Online (Sandbox Code Playgroud)

我刚看了一下我自己的MDI应用程序,我可以看到我有类似的代码来处理这个问题.如果它不是在10年前写的,我可能早就记得了!