我无法在打开和保存对话框中启用Delphi上下文敏感的帮助

7

我有一个使用Delphi 2006编写的应用程序,并带有一个CHM帮助文件。除了无法让“打开对话框”(TOpenDialog)和“保存对话框”(TSaveDialog)上的“帮助”按钮连接到帮助文件外,一切都运行正常。

下面是一个简单的演示程序。单击按钮2可以打开帮助文件并显示正确的页面。单击按钮1可以打开对话框,但在对话框中单击帮助按钮没有任何效果。

unit Unit22;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,
  HTMLHelpViewer ;

type
  TForm22 = class(TForm)
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form22: TForm22;

implementation

{$R *.dfm}

procedure TForm22.Button1Click(Sender: TObject);
begin
OpenDialog1.HelpContext := 10410 ;
OpenDialog1.Execute ;
end;

procedure TForm22.Button2Click(Sender: TObject);
begin
Application.HelpContext  (10410) ;
end;

procedure TForm22.FormCreate(Sender: TObject);
begin
Application.HelpFile := 'c:\help.chm' ;
end;

end.
1个回答

13

使用默认设置,TOpenDialog的帮助消息处理不起作用(您应该将其提交到Quality Central)。

具体原因是因为Windows将帮助消息发送到对话框的父窗口,而不是对话框本身,因此除非您的表单设置了处理它,否则它会被忽略。

解决方法是将Application.ModalPopupMode设置为pmAuto,而不是默认值pmNone。您可以在正常启动代码期间执行一次,或在显示对话框之前执行。当设置为此值时,Delphi会创建一个中间窗口(Dialogs.pas::TRedirectorWindow),可以正确地处理该消息。

如果由于某种原因无法更改ModalPopupMode,则需要在您的表单上处理该消息,如我所说:

TForm22 = class(TForm)
...
  procedure WndProc(var Message: TMessage); override;
end;

initialization

var
  HelpMsg: Cardinal;

procedure TForm22.WndProc(var Message: TMessage);
begin
  inherited;
  if (Message.Msg = HelpMsg) and (OpenDialog1.Handle <> 0) then
    Application.HelpContext(OpenDialog1.HelpContext);
end;

initialization
  HelpMsg := RegisterWindowMessage(HelpMsgString);
end.

谢谢。更简单的修复方法奏效了(在重写的CreateWnd()方法中调用Application.ModalPopupMode := pmAuto)- 我不知道这可能会对我的应用程序产生什么其他副作用。我想退出时不需要做任何事情,因为TApplication实例已经不存在了。 - rossmcm
@user89691:它会产生一个副作用,即每个打开的表单都将“归属”于打开它的表单。这意味着当“父”表单关闭时,它也将被关闭。如果您需要更多控制,请使用pmExplicit作为PopupMode,并显式设置每个表单的PopupParent...,“归属”(在括号中)因为表单的实际父级不受影响,只有它的PopupParent受到影响。 - Marjan Venema
好的,我还有点困惑。CreateWnd重写正在工作,那么保持这种方式安全吗?或者我的TOpenDialog和TSaveDialog是自动创建的(即组件已在设计时放置在窗体上)。所以我可以:1)在调用Execute之前保存Application.ModalPopup的当前值。2)然后将Application.ModalPopup设置为pmAuto。3)在调用Execute之后,将Application.ModalPopup恢复到其保存的值。这似乎有效,并且具有优势,因为我不太可能在其他地方破坏它,因为一切都保持原样。 - rossmcm
将其保持原样应该是安全的。使用pmAuto更接近其他非Delphi应用程序的行为。 - Zoë Peterson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接