Jump to content
DennisTW

Can't make a popup form go behind the main form in z-order

Recommended Posts

Clicking mainform won't bring it in front of SubForm
The following behaviour is different from Lazarus.
procedure TForm1.BtnShowFormClick(Sender: TObject);
begin
  SubForm := TForm.Create(Owner);
  SubForm.Show;//this will make SubForm appear in front of the current Form1.
      //Even if I click on Main Form1, it won't bring Form1 in front of SubForm again.
      //what should I do to bring Form1 in front of SubForm again?
      //I already tried bringtofront and sendtoback
end;

Share this post


Link to post
3 minutes ago, DennisTW said:

Clicking mainform won't bring it in front of SubForm
The following behaviour is different from Lazarus.
procedure TForm1.BtnShowFormClick(Sender: TObject);
begin
  SubForm := TForm.Create(Owner);
  SubForm.Show;//this will make SubForm appear in front of the current Form1.
      //Even if I click on Main Form1, it won't bring Form1 in front of SubForm again.
      //what should I do to bring Form1 in front of SubForm again?
      //I already tried bringtofront and sendtoback
end;

In Delphi the main form (the one created first by an Application.CreateForm statement in the DPR file) is the API owner of all forms created later, so it is lower in the Z-order. It is also the only form having a taskbar button. Lazarus seems to behave like old Delphi versions (before Windows Vista), where the zero-size Application window was the API owner of all forms and owned the taskbar button. This made all forms siblings in the Z order and allowed any form to be covered by the main form. You can get this behaviour back in Delphi by setting

Application.MainformOnTaskbar := false;

in the DPR file, but that is not recommended since it does not work well with the taskbar in modern Windows versions. If you really need to you can uncouple a form from the main form in Z-order by overriding its CreateParams method.

    // in form declaration
    Procedure CreateParams( Var params: TCreateParams ); override;


Procedure TFormX.CreateParams( Var params: TCreateParams );
begin
  inherited CreateParams( params );
  params.wndParent := 0; //or Application.Handle
  // the following gives the form its own taskbar button
  params.ExStyle := params.ExStyle  or WS_EX_APPWINDOW;
end;

 

Share this post


Link to post
On 9/13/2022 at 5:08 PM, DennisTW said:

It works. Thanks so much. 

You'll get several annoying glitches with this setting like window thumbnail displayed incorrectly, not working minimize command with Win+Down and so on

Share this post


Link to post
7 hours ago, Fr0sT.Brutal said:

You'll get several annoying glitches with this setting like window thumbnail displayed incorrectly, not working minimize command with Win+Down and so on

Agreed.  Embarcadero has tied way too many things in the VCL's internals to the TApplication.MainFormOnTaskbar property, making it a do-all toggle switch to enable/disable all kinds of behaviors it was never meant to toggle.  IMHO, they should never have made its scope reach more than it was originally intended for.  Introducing MainFormOnTaskbar at the TApplication level was the wrong design choice to begin with, it should have been introduced at the TForm level instead (like WinForms did with its Form.ShowInTaskbar property), and NOT touch anything other than what its name suggests.  But that is just my opinion...

Edited by Remy Lebeau
  • Like 3

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×