Wednesday, October 31, 2007

Minimize Child Forms Independent of the Main Form

Bagaimana jika child form dari MDI form tetap tampil saat MDI Form di minimize ?

By design, Delphi applications only have one button on the Windows Task Bar for the whole application. When you, for example, minimize the main form of an SDI application, Delphi minimizes the main form and than hides all other windows in the application as well.


SDI means Single Document Inteface. By default, the FormStyle property of all Delphi forms added to the application is set to fsNormal, so that the IDE assumes that all new applications are SDI applications.

Being an SDI application, does not mean you can not have more than one form in the application. In most cases, of course, you will have more than one form - but only one form is the main form of the application.

The main form is the first form created in the main body of the application. When the main form closes, the application terminates. As stated, in an SDI application, when the user minimizes the main form, all other forms get hidden too. Also, only the main form (to be precise, the application) will have a button on the task bar. When a child form is minimized it gets minimized to the Windows Desktop.

Note: contrary to the SDI, in an MDI application, more than one document or child window can be opened within a single parent window. FormStyle property for a MDI parent is fsMDIForm.

Power to the Child Forms!

Let's say you do not want child forms to hide when the main form minimizes. What you need to do is to change the ExStyle of the Params property in the overriden CreateParams method. What's more, you also need to change the parent window of a child form - set it to Windows Desktop.

This is how the CreateParams should look:


___TChildForm = class(TForm)
___procedure CreateParams(var Params: TCreateParams) ; override;


procedure TChildForm.CreateParams(var Params: TCreateParams) ;

___Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;

___Params.WndParent := GetDesktopWindow;
By setting the child form's parent window handle to the Desktop, you remove the link that would normally force the whole application to come to the top when this form comes to the top.
By design, all secondary forms point to the main form of the application for parentage. Clicking on a secondary form's taskbar button while another application is active will bring all the applications forms to front. By using GetDesktopWindow API you change this behaviour.

That's it. Simply override the CreateParams of every child form type in your project and have them minimize independently of the main form.

Note: you could have a base child form class with overriden CreateParams, then have all your child forms inherit the base class.

No comments: