![]() |
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
|
MDI 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 |
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.
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.
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. Go 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.
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.
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.
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 |
|