Home | Articles | Links | Contact
 
Title Basic MDI ( Multiple Document Interface) programming with Delphi 5
Description The following article provides the basic knowledge needed to use MDI in Delphi applications. This type of interface is the one used by most Windows applications and allows the user to have multiple document windows open at the same time
Date 2000/08/15
Last revision
Related articles

Tile, cascade, arrange and list mdi child windows
ActiveMDIChild versus merging the main form menu and the child window menus in a mdi application


No mice allowed beyond this pointMDI is the standard interface for Windows applications. When using a MDI application, the user can have several document window open at the same time. This interface improves user performance by allowing them to see data coming from different documents, quickly copy data from one document to another and many other functions.

Some really basic skills using Delphi are required to follow this article. Although the text has been written for Delphi 5, it should work with any other version of Delphi. If you find any problem when following this article or you find any mistake, please mail me.

Creating the project
Setting the MDI properties for the main window
Creating the child window ( document window)
Dynamic creation of documents
Accesing the document window

Creating the project

First of all you will need a new Delphi project. You can create a new one by selecting "New Application" from the "File" menu. We should create now a new folder and store the main form files and the project files in this new folder.


Setting the MDI properties for the main window

The project we have just created contains only one form. This one will be the parent window that will contain all the document forms. To transform the main window into a parent window you only have to select it, then go to the Object Inspector and set "fsMDIForm" as the value for the "FormStyle" property. With this property set, your main window has been told to be a container for some other windows in your application.


Creating the child window ( document window)

Now that we have a parent window, we will need a child one. Create a new form by selecting "New form" from the "File" menu. No mice allowed beyond this pointGo to the Object Inspector for the new form and set "fsMDIChild" as the value for the "FormStyle" property. Now the second form has been told to be a child. In one project, you can have only one form with the "FormStyle" property set to "fsMDIForm", so there is only one form this window could be child of.

To create an example of document window, you could add a TMemo component to this form, and then set the "Align" property to "alClient". Double click on the "Lines" property to clear it and we will have a simple window capable of holding unformated text documents.

With this two windows defined you can run your first mdi application. You will notice that the document window is automatically displayed inside the main window. This is because Delphi configures any new form we create to be automatically initialized when the application starts and a mdi child window can not be hidden, so when the application starts running it creates the main window and then creates the child window that must be displayed immediately.

With these simple steps we have built the framework of the mdi structure. However, we still do not have the option to create new windows in our application.


Dynamic creation of documents

In order to provide a way for the user to create new windows, we will add a main menu to the main form. Look for the "TMainMenu" component in the "Standard" palette, select it and click on the main form. The new "MainMenu1" will be created on the form. Right-click on it to get its context menu and select the "Menu Designer". In the designer, type "&File" to create the first option for the menu and press "Enter". A new option in the menu bar will be created and the new empty drop down menu will be displayed. Type "&New" and press "Enter" to create the first option for that menu. Once you have added these new options you can close the designer and go back to the main form where the main menu will be now active. Select "File" and "New" in the main form to create an event handler for the OnClick event of the "New" option and type the following code:

procedure TForm1.New1Click(Sender: TObject);
begin
  Application.CreateForm( TForm2, Form2)
end;

This line tells the "Application" object running your program to create a new form of class TForm2 and own it. If we try to compile this, we will receive an error because we have not tell Delphi that the main form was going to use TForm2. To do so, select "File" and "Use unit", and choose the unit where the child window is defined. You will notice that Delphi adds this unit to the "Uses" clause of the main form.

Now you can run your mdi application and start creating new child windows by selecting "New" in the "File" menu of the main form. You can type on them, you can change from one to another by pressing Ctrl+TAB, etc. Now all the child windows have the same structure and behaviour but different data. They are all independent.

If you try to close one of them, you will realize that it will only minimize itself to the bottom of the main window. This is because the default action when you close a window is hiding it and, as we said before, it is not posible to hide a mdi window. To close a mdi window you have to free it and release the memeory occupied by it. Close your application and open in Delphi the definition of the child window. Click on the "TMemo" and then press ESC to select the whole form. Press F11 or select the "Object Inspector" and look for an event called "OnClose" and type the following lines of code:

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree
end;

With this code we change the default action for the close event from hide to free, so the windows we try to close will disappear from the main window instead of minimizing themselves.


Accesing the document window

Now that we have our main window created and we have the option to create child windows, we should have a way to access the data in the selected child window. For example, we could have an option in the file menu called "Clear" to clear the content of the selected child window. First of all, we have to edit the main menu and add the new option, then select it to write an event handler for the OnClick event. The code for the event handler could be the following:

procedure TForm1.Clear1Click(Sender: TObject);
begin
  if Assigned( ActiveMDIChild) then
    ( ActiveMDIChild as TForm2).Memo1.Clear
end;

The ActiveMDIChild property of the form returns the active child window if any. If there is no active mdi child, this property points to nil so we have to check it before we use it. Since ActiveMDIChild returns a reference to a form, we can not use it directly as an object of class TForm2, we have to perfom a typecast by using the reserved word "as". Once we have converted ActiveMDIChild to TForm2 we can access the TMemo object that belongs to that class of forms and clear it.


What's next?

Many other things can be done with a mdi application, you can choose wether you want the application to create the first child window automatically when the application is initialized, you can add a main menu to the child form which will be merged with the main menu of the application, you can add options to your menu for having a list of child windows or for organizing them. You may have a look at the following articles:

Tile, cascade, arrange and list mdi child windows
ActiveMDIChild versus merging the main form menu and the child window menus in a mdi application

Was this article useful for you?
Yes No
Any other comments will be welcome

Home | Articles | Links | Contact