Avoiding MDI: Making a form a child of another form

Avoiding MDI: Making a form a child of another form

How do I make a form a child of another form without having to resort to the overhead of MDI?


MDI provides an easy and well-established way for developers to create applications in which one form can contain several forms in a Parent-Child relationship. But because MDI is so well-defined, it takes up a lot of resources. Especially in the case where you want to create a child form for the express purpose of being a tool bar of sorts, carrying the MDI along for just this purpose can be a bit of a waste of resources. But there is a work-around for it.

All Delphi forms inherit a very useful method from TWinControl called CreateParams. You can override this method to achieve various behaviors in the way a form diplays when it’s created. Without going into a lot of esoteric Windows API lingo, CreateParams initializes a TCreateParams structure that contains generic base values defining a window’s appearance. The record structure is listed below:

type    TCreateParams = record    Caption: PChar;    Style: Longint;    ExStyle: Longint;    X, Y: Integer;    Width, Height: Integer;    WndParent: HWND;    Param: Pointer    WindowClass: TWndClass;    WinClassName: array[0..63] of Char;  end;

We won’t go into any detail about this structure because it’s beyond the scope of this discussion. I’ll leave it up to you to peruse the online help for a detailed discussion of the topic. However, note that there are several things you can change in the structure itself. With respect to our current discussion, to achieve our desired result of having a form be the child of another form, we’ll manipulate this structure within our CreateParams method.

It’s actually a fairly trivial thing to make a form act as a child form. All we have to do is the following:

  1. Create the form with a Child window style
  2. Notify Windows that the form has a new parent
  3. Notify Delphi that the form has a new parent

It couldn’t get easier than this. Here’s the code for the method that accomplishes the steps above:

unit child;interfaceuses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;type  TChildForm = class(TForm)    procedure FormClose(Sender: TObject; var Action: TCloseAction);    procedure Button1Click(Sender: TObject);  private    procedure CreateParams(var Params : TCreateParams); override;  public    { Public declarations }  end;var  ChildForm: TChildForm;implementation{$R *.DFM}procedure TChildForm.CreateParams(var Params : TCreateParams);begin  inherited CreateParams(Params);  with Params do begin    {Set the Child’s style to WS_CHILD}    Style := (Style OR WS_CHILD) AND NOT WS_POPUP;    X := 50;    Y := 50;    Width := 200;    Height := 150;    {Let Windows know about the relationship}    WndParent := Application.MainForm.Handle;  end;  {Let Delphi know about the relationship}  Parent := Application.MainForm;end;procedure TChildForm.FormClose(Sender: TObject; var Action: TCloseAction);begin  Action := caFree;end;procedure TChildForm.Button1Click(Sender: TObject);begin  ShowMessage(‘Hello world!!!’);end;end.

Nothing really complex about that, right? All I did with the TCreateParams structure was to set the window style to WS_CHILD so the window is created a child, then set the parent-child relationship with a couple of assignment lines. With this sample, I simply embedded a TButton on the form to display the obligatory test message Hello world!!! But you can make the form do practically anything you want. Also, note the FormClose method: I’ve set it so that the form is destroyed when it is closed. However, you can substitute the Action := caFree; with Action := caMinimize to mimic the behavior of an MDIChild form.

Since this is a fairly simple tip, I didn’t include a sample application. However, if you want to create a test application to test this concept out, do the following:

  1. Create a new application in Delphi.
  2. Name the main form something like ParentForm to differentiate it from other forms.
  3. Using either the tool bar or File|New Form, create a new form.
  4. Insert the code above in the Child form as above.
  5. Insert a uses statement in the implementation of your MainForm and declare your child form’s unit name.

Create a child form like this as you would normally create any other form. Here’s some sample code from the main form of my test application:

procedure TForm1.Button1Click(Sender: TObject);var  ChildFrm : TChildForm;begin  ChildFrm := TChildForm.Create(Application);  ChildFrm.Show;end;

This is plain vanilla form creation, so there’s nothing here that you don’t already know how to do. In fact, if you look at all the code above, there’s really nothing so complex that you couldn’t have figured it out sooner or later by yourself.

You might be asking Of what use is this methodology? Well, besides toolbars, I use this technique for creating wizard-like programs. I also use it instead of using notebooks because sometimes my pages can get fairly complex. So to reduce resource utilization, I instead create a bunch of child forms that don’t have any caption bars or borders and are maximized in the client area of the main form. As the user goes from page to page, the components embedded on the pages are created and destroyed on the fly. This may be a bit slower in comparison to having a notebook, but this technique is far less resource-intensive than using a notebook, which would load up all the components at run time.

Share the Post:
XDR solutions

The Benefits of Using XDR Solutions

Cybercriminals constantly adapt their strategies, developing newer, more powerful, and intelligent ways to attack your network. Since security professionals must innovate as well, more conventional endpoint detection solutions have evolved

AI is revolutionizing fraud detection

How AI is Revolutionizing Fraud Detection

Artificial intelligence – commonly known as AI – means a form of technology with multiple uses. As a result, it has become extremely valuable to a number of businesses across

AI innovation

Companies Leading AI Innovation in 2023

Artificial intelligence (AI) has been transforming industries and revolutionizing business operations. AI’s potential to enhance efficiency and productivity has become crucial to many businesses. As we move into 2023, several

data fivetran pricing

Fivetran Pricing Explained

One of the biggest trends of the 21st century is the massive surge in analytics. Analytics is the process of utilizing data to drive future decision-making. With so much of

kubernetes logging

Kubernetes Logging: What You Need to Know

Kubernetes from Google is one of the most popular open-source and free container management solutions made to make managing and deploying applications easier. It has a solid architecture that makes

ransomware cyber attack

Why Is Ransomware Such a Major Threat?

One of the most significant cyber threats faced by modern organizations is a ransomware attack. Ransomware attacks have grown in both sophistication and frequency over the past few years, forcing

data dictionary

Tools You Need to Make a Data Dictionary

Data dictionaries are crucial for organizations of all sizes that deal with large amounts of data. they are centralized repositories of all the data in organizations, including metadata such as