What is an MDI Application?
An application in Visual Basic may be based either on SDI (Single Document Interface) or on MDI (Multiple Document Interface). In MDI application, a single container form maintains a collection of child forms. MDI application allows you to display multiple documents at the same time, with each document displayed in its own window. Applications such as MS-Word, MS-Excel etc, are a few examples of MDI applications.
The main window or the container is called as Parent window or Frame. In Visual Basic, Parent window is an MDIForm. An MDIForm can display multiple child forms in its client area. MDIForm can also arrange child forms.
A child form is a form for which MDIChild property is set to true. At run time the program will create multiple child forms. Each child form will be an instance of the form that has its MDIChild property set to true.
Note: An application in Visual Basic can contain only one MDIForm.
In this chapter, we will develop an editor that works similar to Notepad but allows users to work with multiple documents at the same time. With this application you can open more than one text file and edit those text files at the same time. In other words, it is like an MDI version of Notepad.
To Create an MDI Application take the following steps:
- Create a new project using File -> New Project and select Standard Exe as the type of the project.
- At this stage a new project is created with just one form. The form that is created by Visual Basic is a normal form. But as our application is based on MDI, it needs an MDIForm.
- Add an MDIForm to project using Project -> Add MDIForm.
- Visual Basic adds an MDIForm to the current project.
- After MDIForm is added to current project, Add MDIForm option in Project menu will be disabled. Remember there can be only one MDIForm in a Visual Basic project.
Adding Menu to Application
Add required menus to MDIForm by following the steps below.
- Make MDIForm active form in the project.
- Select Tools->Menu Editor
- Add the following menu using Menu Editor
|New||Creates a new document. It creates a new child form and displays empty window.|
|Open… F3||Allows user to select a text file. Creates a new child window and displays the contents of the text file for editing in that window.|
|Close||Closes the currently active document. Takes confirmation before closing a document, if document was modified but not saved.|
|Save F2||Saves changes made to current document. If current document is a new document, it will prompt user to enter a filename using Save As dialog box.|
|Save As||Allows current document to be saved under a different filename.|
|Prints the current document to printer.|
|Exit||Terminates the application. Takes confirmation before the application is terminated.|
|Cut Ctrl + X||Cuts the selected text in the current document and places the text on the clipboard.|
|Copy Ctrl + C||Copies the selected text in the current document to clipboard.|
|Paste Ctrl + V||Extracts text from clipboard and pastes it into current document.|
|Cascade F5||Arranges all open windows using cascade format, where title bars of all open windows will be displayed.|
|Tile Horizontal||Tiles all open windows horizontally.|
|Tile Vertically||Tiles all open windows vertically.|
|Arrange Icons||Arranges all minimized windows.|
|Windows list||Displays captions of all open child forms.|
|About||Displays about dialog box.|
Displaying Window List
One of the common features of an MDI application is Window menu displaying list of open windows. For example, in MS-Word, you get the list of open documents at the end of the window menu. Visual Basic IDE is also an MDI application. If you see Window menu of Visual Basic IDE while working with a project, it looks like figure 12.1. As you can see at the Window Menu the list of open windows are displayed
Figure 12.1: Window List from Window menu of Visual Basic IDE.
To display windows list in MDI application:
- Invoke Menu Editor of MDIForm using Tools -> Menu Editor when MDIForm is active
- Select Window menu in the list of menu. As we want to display list of windows at the bottom of Window menu.
- Turn on WindowList checkbox as shown in figure .12.2.
That’s all you have to do to display the list of windows at the bottom of Window menu. Visual Basic takes care of adding and removing windows from the list as you open and close documents.
Figure 12.2: Enabling the display of list of windows at the bottom of Window menu.
Making Form1 MDIChild form
Now our project contains two forms – MDIForm1 and Form1. MDIForm1 is the parent that forms the base for the application. Form1 is the form that displays the contents of the file and allows user to edit. We take multiple copies of Form1 at run time to display multiple documents. In order to display copies of Form1 within MDIForm1, first we have to make Form1 a child form.
To make Form1 an MDI Child form:
- Invoke Properties Window of Form1 by selecting the form and pressing F4.
- Change MDIChild property to
Child form will display the contents of the selected file and also allows user to edit the contents. To display the contents of the selected file, we place a text box in child form. The textbox will occupy the entire client area of the child form and it also contains scrollbars to allow user to scroll.
Place a textbox and change its property as follows.
- Place a textbox on the form. The position and size of the textbox are not so important because they are changed at run time using Resize event (see listing 12.1) of the form so that textbox occupies the entire client area of the form.
Private Sub Form_Resize() ‘Make textbox occupy the entire client area’.
Text1.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
Listing 12.1: Filling the entire client area of the form using resize event of the form.
- Change the MultiLine property to True, and Scrollbars property to 3-both.
Changing Startup Object of the Project
If you run the project now, Form1 will be displayed as the first form. But we want MDIForm to be displayed first. To display MDIForm1 as the first form in the project we have to change Startup Object property of the project.
To change startup object:
- Select Project -> Project Properties (In place of Project in Project Properties option, the name of the current project name is displayed).
- Visual Basic displays project properties dialogbox (see figure12.3).
- Select General tab if it is not selected.
- From Startup Object drop down, select MDIForm1 to make MDIForm1 the startup object.
- Click on Ok to close properties dialogbox.
Now, if you run the project, MDIForm1 will be displayed as the first form (see figure 12.4)
Writing code for Options in File menu
The following section will explain the code for options of File menu.
Figure 12.3: Changing startup object of the project.
Figure 12.4: MDIForm1 when it is run.
Writing code for New option
We will now write code for New option of File menu. When user selects New option from File menu a new window is to be displayed so that user can start typing text. Subsequently, if user chooses Save option then the typed contents will be saved under the given name.
New option creates a new copy of Form1 and displays that copy with Noname as the caption of the form. As we have to prompt user, if user is trying to close the document without saving changes, we use Tag property of the form. Tag property of the form will be set to 0 in the beginning. Tag property is set to 1 whenever user makes a change to the content. Again Tag is set to 0 when user saves changes. That means at the time of closing document if Tag is set to 1, it means user is trying to close a document that was modified but not saved. In this case, program has to prompt user to save pending changes. We will create code for close option later.
Here is code for new option.
Private Sub mnunew_Click()
Dim f As New Form1 ‘ create a new copy of Form1
f.Caption = “Noname”
f.Tag = 0 ‘ not modified
f.Show ‘ display form
Listing 12.2: Code for new option of file menu.
Writing code for Open Option
For this option, as we have to prompt the user to select a filename. First of all to use open dialog, we have to load common dialog control into project.
To load common dialog control:
- Select Project-> Components
- Move down until you get to Microsoft Common Dialog Control 6.0 and select it (turn on the checkbox).
- Click on Ok button
Visual Basic places the control in Toolbox.
- Place common dialog control on MDIForm1.
Open option of File menu does the following:
- Accepts a filename from user through Open common dialog box.
- Creates a new instance of Child form (Form 1).
- Loads the content of selected file into the text box of child form.
- Displays the child form.
Here is the code for Open option of File menu.
Private Sub mnuopen_Click()
‘Create a New instance of form
Dim nf As New Form1
Dim oneline As String, filecontent As String
‘ trap error that might occur
On Error GoTo errlbl
‘ display open dialog box to user
.Filter = “Text files|*.txt|All files|*.*”
’cause error if user doesn’t select any file
.CancelError = True
‘ user has selected a file. Read the content and display content
‘ in textbox
‘ change mouse pointer to indicate system is busy
Screen.MousePointer = vbHourglass
‘ open file
Open .FileName For Input As #1
Do Until EOF(1)
‘ read one line at a time
Line Input #1, oneline
‘ concatenate line along with new line to lines read so far
filecontent = filecontent & oneline & vbCr & vbLf
‘ load the text into textbox of child form
nf.Text1 = filecontent
‘ set Tag to 0 to indicate that content is not modified
nf.Tag = 0
‘ change caption to file name
nf.Caption = .FileName
‘display child form
‘ reset mouse pointer
Screen.MousePointer = vbDefault
‘ ignore the error and free memory allocation to nf and quit
Set nf = Nothing
Listing 12.3: Code for Open option of File menu.
Writing code for Save and Save As options
Save option saves the changes made to current form. If current form contains a new document (with caption property set to Noname) then Save option works like Save As, otherwise Save saves the changes made to current document.
Save As prompts the user to enter a new filename and then saves the contents in the new filename.
This is also invoked by Save option when user is saving a new document.
As both Save and Save As options write the document into a file, it is better to implement code as a separate procedure.
General procedures such as SaveFile in this case, are accessed generally from more than one form. So it is better to create a code module and place all such general procedures into code module because procedure placed in code module can be accessed through the project.
Creating SaveFile procedure in Code module
First let us create a new code module and then create a SaveFile procedure in code module.
To add a code module to project:
- Select Project -> Add Module.
- Visual Basic adds a code module to project with default name Module1.
To create SaveFile procedure:
- Make code module active.
- Select Tools -> Add Procedure
- When Visual Basic displays Add Procedure dialog box, enter SaveFile as the name of the procedure and click on Ok.
- In code window enter the code shown in listing .
Public Sub SaveFile(fn As String, content As String)
Open fn For Output As #1
Print #1, content
‘ set tag property to 0 to indicate that
‘ changes are saved
MDIForm1.ActiveForm.Tag = 0
Listing 12.4: Code for SaveFile procedure.
The following is the code for Save and Save As options.
Private Sub mnusave_Click()
‘ call Save As if name of the file is Noname
If .Caption = “Noname” Then
‘ call save as
SaveFile .Caption, .Text1.Text
Private Sub mnusaveas_Click()
‘trap error that might occur
On Error GoTo errlbl
‘display save as dialog box to user
‘ set the file name as the default
.FileName = MDIForm1.ActiveForm.Caption
.Filter = “Text files|*.txt|All files|*.*”
’cause error if user doesn’t any file
.CancelError = True
‘ set new file to caption
MDIForm1.ActiveForm.Caption = .FileName
‘ save file contents to new filename
SaveFile .FileName, MDIForm1.ActiveForm.Text1.Text
‘ignore errors and continue
Listing 12.5: Code for Save and Save As options of File menu.
As you can see from the code, both these event procedures make use of SaveFile procedure created in code module.
Note: ActiveForm property of MDIForm refers to the form that is currently active among child forms.
Code for Close option of File menu
Whenever user chooses Close option from File menu, the active form is to be closed. But if active form has modifications that were not saved then you should prompt the user to save the modifications.
Clicking on close button (X) may also close a child form. In this case also user should be prompted to save modifications.
Prompting user to save changes using QueryUnload event
QueryUnload event occurs just before a form is unloaded. QueryUnload event can cancel unloading form if you set Cancel parameter to True. We use QueryUnload event to prompt the user and take necessary action, as this event occurs in both cases – user clicking on close button of the form and form is getting unloaded because of program executing Unload statement. The second method is used for Close option of File menu.
The following is the code for Close option of file menu.
Private Sub mnuclose_Click()
‘ unload active form
Listing 12.6: Code for close option of file menu.
The following is the code for Change event of Text box in child form. This event occurs whenever text in the textbox changes. At this event we set Tag property of the form to 1 to indicate the content of the textbox has changed.
The final in this context is the code for QueryUnload event of the child form.
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
‘ check whether changes are pending
If Me.Tag = 1 Then
‘ display confirmation box
resp = MsgBox(“Do you want to save changes?”, vbYesNoCancel _
+ vbQuestion, “Save Changes”)
‘ if user has selected Cancel button
If resp = vbCancel Then
‘ cancel unload process
Cancel = True
‘ if user has selected Yes to save changes
ElseIf resp = vbYes Then ‘ save changes and then quit
SaveFile Me.Caption, Text1.Text
Listing 12.7: Code for Queryunload event of form.
Private Sub Text1_Change()
‘ change tag property to indicate modification
Me.Tag = 1
Listing 12.8: Code for change event of text box.
The prompt displayed by MsgBox function will be identical to the one shown in figure 12.5.
Figure12.5: Message box displayed when user tries to quit without saving changes.
The following will be the action taken for each of the buttons.
Yes Saves the modification and then closes the form.
No Closes the form without saving the modifications.
Cancel Cancels closing process.
Writing code for Print option in File menu
Print option prints the contents of current document to default printer. Printer object is used to print to default printer.
Here is the code to print current document.
Private Sub mnuprint_Click()
‘ print current document to printer object
Listing 12.9: Code for print option of file menu.
Writing code for Edit menu
Code for edit menu is much like the code that we have written in chapter 11 for clipboard object. I do not feel any need to explain the code here. For details, please see chapter 11(System Objects).
The code for Cut, Copy and Paste options and Edit menu is given in listing 12.10.
Private Sub mnuedit_Click()
‘ disable all options
mnucut.Enabled = False
mnucopy.Enabled = False
mnupaste.Enabled = False
If MDIForm1.ActiveForm.Text1.SelText <> “” Then
‘ disable all options
mnucut.Enabled = True
mnucopy.Enabled = True
If Clipboard.GetFormat(vbCFText) Then
mnupaste.Enabled = True
Private Sub mnucopy_Click()
‘copy the selected text on to clipboard
Private Sub mnucut_Click()
‘copy the selected text on to clipboard
‘cut the selected text
MDIForm1.ActiveForm.Text1.SelText = “”
Private Sub mnupaste_Click()
‘Place the text that is existing in clipboard at
‘the cursor position
MDIForm1.ActiveForm.Text1.SelText = Clipboard.GetText
Listing 12.10: Code for Edit menu and its options.
Writing code for Window menu
All options in window menu make use of Arrange method of MDIForm. Arrange method is used to arrange child forms of MDIForm in the specified format. Here is the complete syntax of Arrange method.
The arrangement may be any of the values given below.
|vbCascade||0||Cascades all nonminimized MDI child forms|
|vbTileHorizontal||1||Tiles all nonminimized MDI child forms horizontally|
|vbTileVertical||2||Tiles all nonminimized MDI child forms vertically|
|vbArrangeIcons||3||Arranges icons for minimized MDI child forms|
Here is the code for options in Window menu.
Private Sub mnucascade_Click()
Private Sub mnuth_Click()
Private Sub mnutv_Click()
Private Sub mnuai_Click()
Listing 12.11: Code for options in Window menu.
Creating About dialog box
Visual Basic provides a template for About dialog box. All you have to do is change the required properties of labels that are placed in the about dialog box. This is the process to add about dialog box to the project.
To add About dialog box to project:
- Select Project -> Add Form.
Visual Basic displays a list of predefined forms.
- Select About dialog and click on Open
Visual Basic adds an about dialog to current project and form is given name frmAbout.
At design time, About dialog box that is added would look like figure 12.6.
To invoke About dialog box:
Write code for click event of About option in Help menu. About dialog box is to be displayed as a modal window (by using vbModal option for Show method).
Private Sub mnuabout_Click()
Listing 12.12: Code to invoke about dialog box.
Figure 12.6:About dialog box at design time.
Note: About dialog box takes properties of current project and fills some of the labels on the form. You have to fill the remaining with the required information.
Now we have reached the end of the development. Now it is time to run the application and test all its features.
- Run project using Run-> Start option or F5 or by clicking on Start icon in toolbar.
- When Visual Basic displays MDIForm, choose File->New option to create a new document as shown in figure 12.7. Enter some text in the text box.
- Now try to save this document by pressing F2 or by selecting File -> Save.
- As the document is new document, Save option will prompt you to enter the name of the file in which the document is to be saved.
- Enter filename Sample.txt.
- Close the file by choosing File->Close.
- Open the file sample.txt using File-> Open.
- Enter one more line to the document.
- Try to close the file using File->Close. As we are trying to close without saving the changes, program displays message box prompting you to save changes. See figure 12.8.
- Choose Cancel to cancel closing operation.
- This time click on Close button of the child form.
- This will also result in the same prompt. Select Yes button in message box to save changes and then quit.
- Now choose File->New options for a few times to create a few new MDI child windows.
- Choose Window->Tile Vertical to file windows vertically.
At this stage MDIForm looks like figure 12.9.
- Exit MDIForm using File->Exit.