Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I move a Delphi form in front of the other?

I have an application which always shows at least two forms at the same time.

Generally I have a job list in a child form of the main form with the relevant details shown on the main form. Other details may be managed with ShowModal.

The current issue is that users have recently requested that the Main Form can be dragged in front of the Job List.

As far as I can see, because the Job List Form is created after the Main Form and called to Show from the Main Form it gets the "front" position.

Is there any way this can be changed at runtime, i.e. can I set the Active form to be at the front?

like image 208
Dan Kelly Avatar asked Nov 01 '11 16:11

Dan Kelly


2 Answers

Note: In the rest of this answer the terminology owned takes the meaning used by the Windows documentation. This differs from the meaning of the same term in the VCL.

What is happening is that your job list window is a top-level owned window.

Being owned places several constraints on a window.

  • An owned window is always above its owner in the z-order.
  • The system automatically destroys an owned window when its owner is destroyed.
  • An owned window is hidden when its owner is minimized.

If you want your job list window to be capable of being below the main window in the z-order, it cannot be owned by the main window. You can achieve this as follows:

class TJobListForm = class(...)
protected
  procedure CreateParams(var Params: TCreateParams); override;
...
procedure TJobListForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := Application.Handle;
end;

This makes the job list window an top-level window owned by the hidden application window. Or alternatively like this:

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

This makes the job list window an unowned top-level window. As such it now receives a button in the taskbar.

Making such changes will have far reaching effects for your application. The second and third bullet points on the list above are obvious impacts. The behaviour of your windows when minimised and their interaction with the taskbar would also be affected. I've only scratched at the surface here. You will probably find that making your job-list window no longer be owned by the main window has quite an impact on your program. You'll discover that Windows does a lot of work for you behind the scenes for owned window. You may need to reproduce some of that work if you switch to an unowned window.

like image 103
David Heffernan Avatar answered Sep 28 '22 07:09

David Heffernan


As long as the Job List Form is not a child of any other window (ie, its Parent property is not set and its CreateParams() method is not overriden to set the TCreateParams.WndParent field), and it is displayed using its Show() method instead of its ShowModal() method, then the user should be able to freely switch between the two windows at will.

like image 44
Remy Lebeau Avatar answered Sep 28 '22 07:09

Remy Lebeau