My form form is hidden behind the main form when calling TsaveDialog

My application is based on MainForm, DetailForms and DialogForms. In the taskbar, I see MainFormButton, as well as DetailForms. Therefore, I use:

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

I am using delphi 2010 and I installed Application.MainFormOnTaskbar: = True; When I use PromptForFileName or TSaveDialog in Detailform, then DetailForm is behind Mainform. DetailForm returns after closing the dialog.

When I use DialogForm (Showmodal of TForm with the PopupMode: pmAuto property), my DetailForm stays between the main and the dialog. How can I get TSaveDialog as showmodal with the PopupMode: pmAuto property or how can I prevent my detailform from falling behind the main form

Demo:

 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. 
+6
delphi
source share
1 answer

Step 1 is that you should not make the desktop window the owner of your form. Raymond Chen explains why not.

To understand what’s going on, you need to read “Window Features” on MSDN to get a clearer picture of window ownership. And be very careful that window ownership is a concept completely unrelated to ownership of the Delphi component. In Delphi terms, window ownership is controlled by the PopupParent property.

As explained in the comments, you want both forms to be unaudited, top-level windows. The basic form is automatically as follows. For the details form, you need to set WndParent to 0 and that it:

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

The final step is to make sure that the save dialog is in the correct order. To do this, specify the owner when calling Execute :

 Self.SaveDialog1.Execute(Self.Handle); 

So, in the end you need to make three changes:

  • Set the part shape of WndParent to 0 .
  • Remove the advanced style WS_EX_APPWINDOW , it is not needed for an idle top-level window.
  • Pass the part form handler when you call Execute in the save dialog box.

Update

Turns out you're using XP, and the Delphi code that displays the dialog with the file is garbage. Although you pass the handle to the Execute method, which is ignored, the main window handle is used as the owner of the dialog box. And that is why the main window comes to the fore.

You can get around this by setting Application.ModalPopupMode to pmAuto . You should probably install this in your .dpr file.

More on this here: http://blogs.embarcadero.com/abauer/2005/09/30/21517

+11
source share

All Articles