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 はメインとダイアログの間に留まります。プロパティ PopupMode: pmAuto を使用して showmodal のように TSaveDialog を強制するにはどうすればよいですか、または詳細フォームがメインフォームの後ろに移動するのを防ぐにはどうすればよいですか

デモ:

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プロパティによって制御されます。

コメントで明確にされているように、両方のフォームを所有されていないトップレベルのウィンドウにする必要があります。メインフォームは自動的にそれです。WndParentあなたが設定する必要がある詳細フォームについては、0それだけです:

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

最後のステップは、保存ダイアログが適切に所有されていることを確認することです。これを行うには、呼び出すときに所有者を指定しますExecute

Self.SaveDialog1.Execute(Self.Handle);

つまり、要約すると、次の 3 つの変更を行う必要があります。

  1. 詳細フォームWndParentを に設定し0ます。
  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 に答える