6

我的应用程序基于 MainForm、DetailForms 和 DialogForms。在任务栏上,我可以看到 MainFormButton 和 DetailForms。因此我使用:

procedure <DetailForm>.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent:= GetDesktopWindow;  
end; 

我使用delphi 2010,并且设置了 Application.MainFormOnTaskbar:= True; 当我在 Detailform 中使用 PromptForFileName 或 TSaveDialog 时,DetailForm 将位于 Mainform 后面。DetailForm 在关闭对话框后返回。

当我使用 DialogForm(带有属性 PopupMode: pmAuto 的 TForm 的 Showmodal)时,我的 DetailForm 将停留在主对话框和对话框之间。如何强制 TSaveDialog 像具有属性 PopupMode: pmAuto 的 showmodal 或如何防止我的 detailform 落后于 mainform

演示:

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

  {$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  oForm: TForm;
begin
  oForm:= Unit2.TForm2.Create(Self);
  oForm.Show;
end;
end.

unit Unit2;

interface

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

type
  TForm2 = class(TForm)

    SaveDialog1: TSaveDialog;
    procedure cxButton1Click(Sender: TObject);
  private
  protected
    procedure CreateParams(var Params: TCreateParams); override;
        { Private declarations }

  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

{ TForm2 }

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent:= 0;   // --> Testing
end;

procedure TForm2.cxButton1Click(Sender: TObject);
begin
  self.SaveDialog1.execute();
end;

end.
4

1 回答 1

12

第 1 步是您不能将桌面窗口设为表单的所有者。Raymond Chen解释了为什么不这样做。

要真正了解正在发生的事情,您需要阅读MSDN 上的Window Features以更清楚地了解窗口所有权。并且要非常小心,窗口所有权是一个与 Delphi 组件所有权完全无关的概念。在 Delphi 术语中,窗口所有权由PopupParent属性控制。

正如评论中所阐明的,您希望这两个表单都是无主的顶级窗口。自动的主要形式就是这样。对于您需要设置的详细信息表单WndParent0就是这样:

procedure <DetailForm>.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := 0;
end; 

最后一步是确保正确拥有保存对话框。为此,请在调用时指定所有者Execute

Self.SaveDialog1.Execute(Self.Handle);

因此,总而言之,您需要进行三项更改:

  1. 将详细信息表单设置WndParent0.
  2. 删除WS_EX_APPWINDOW扩展样式,无主的顶级窗口不需要它。
  3. 调用Execute保存对话框时传递详细信息表单的句柄。

更新

事实证明,您使用的是 XP,并且显示文件对话框的 Delphi 代码是垃圾。尽管您将句柄传递给该Execute方法,但该句柄将被忽略,并且主窗口句柄用作对话框的所有者。这就是主窗口出现在前面的原因。

您可以通过设置Application.ModalPopupMode来解决此问题pmAuto。您可能应该在 .dpr 文件中设置它。

在此处阅读有关此内容的更多信息:http: //blogs.embarcadero.com/abauer/2005/09/30/21517

于 2013-01-24T13:50:11.213 回答