How to Create Hidden MDI Child FormsID: Q115781
|
MDI child forms cannot be loaded without being visible, unlike ordinary
forms. However, you can use the technique described in this article to make
it appear as if loaded MDI child forms are invisible by using form arrays
to hide them. Use this technique to provide faster response or configure
forms dynamically before making them visible.
The example given below shows you how to:
The example code creates an MDI child form (named BackSim) to simulate the
background of the MDI parent form. The sole purpose of the BackSim MDI
child form is to hide the other MDI child forms that lay below it in the Z
order. This makes the other child forms appear invisible or hidden, yet
remain loaded.
The example gives the BackSim MDI child form the following key property
settings:
Property Value
-------------------
Enabled False
ControlBox False
Caption ""
BorderStyle 0 - None
MaxButton False
MinButton False
Sub MDIForm_Resize ()
backsim.Move 0, 0, MDIform1.ScaleWidth, MDIform1.ScaleHeight
End Sub
' The following includes the form and control descriptions as well as
' necessary Function and Sub procedures. Place this code in a single text
' file called MDIFORM1.FRM. so you can load it as a form in Visual Basic.
'
' NOTE: To make the code fit in this article, some of the lines
' are listed using multiple lines. After copying the code into a file,
' modify it to ensure that each line of code exists as one, single line
' in the file. Otherwise, you will receive errors when loading the form in
' Visual Basic.
VERSION 2.00
Begin MDIForm MDIForm1
Caption = "MDIForm1"
ClientHeight = 5412
ClientLeft = 948
ClientTop = 1908
ClientWidth = 7368
Height = 6156
Left = 900
LinkTopic = "MDIForm1"
Tag = "Parent"
Top = 1212
Width = 7464
Begin Menu mnu_children
Caption = "&Children"
Begin Menu mnu_newchild
Caption = "&New Child"
Shortcut = ^N
End
Begin Menu mnu_unloadall
Caption = "&Unload All Children"
Shortcut = ^U
End
End
Begin Menu mnu_Window
Caption = "&Window"
Begin Menu mnu_cascade
Caption = "&Cascade"
Shortcut = ^C
End
Begin Menu mnu_tileh
Caption = "Tile &Horizontal"
Shortcut = ^H
End
Begin Menu mnu_tilev
Caption = "Tile &Vertical"
Shortcut = ^V
End
Begin Menu mnu_sim
Caption = "Simulated &Background"
Index = 0
Shortcut = ^B
End
Begin Menu mnu_showall
Caption = "Show &All Children"
Shortcut = ^A
End
End
End
Sub MDIForm_QueryUnload (Cancel As Integer, unloadmode As Integer)
' Unload all child forms loaded at runtime:
mnu_unloadall_Click
End Sub
Sub MDIForm_Resize ()
' This reference to the properties of the BackSim
' MDI child form causes Visual Basic to implicitly load
' the form. Because MDI child forms cannot be loaded
' without being visible, this shows the BackSim form:
backsim.Move 0, 0, MDIform1.ScaleWidth, MDIform1.ScaleHeight
End Sub
Sub mnu_cascade_Click ()
backsim.ZOrder 1
MDIform1.Arrange 0 ' cascade
tiledflag = 0
End Sub
Sub mnu_newchild_Click ()
' Increment counter for array of child forms:
childcount = childcount + 1
' Decide if new array slots are needed
' or if old (unloaded) slots need to be filled
' First, do empty slots exist:
If childcount <= trackcount Then
' Find empty slot in arrays (menu and childtrack):
lowestfreenum = 1
For i = 1 To UBound(childtrack)
If Not childtrack(i) Then
lowestfreenum = i
Exit For
End If
Next i
' Mark slot as loaded:
childtrack(lowestfreenum) = True
' Load a new menu item for each child form
' under the menu control mnu_sim(0):
Load mnu_sim(lowestfreenum)
' Set a new caption for the new menu item and supply access key:
' Turn the following two lines into one, single line:
mnu_sim(lowestfreenum).Caption =
"Show Only Child Form Number &" & lowestfreenum
' Mark this slot as loaded:
childtrack(lowestfreenum) = True
' Set the tag equal to the childcount
' to allow tracking of self:
child_array(lowestfreenum).Tag = lowestfreenum
' Set unique caption for each child form to cause an
' implicit load and show the child form:
' Turn the following two lines into one, single line:
child_array(lowestfreenum).Caption =
"Child Form Number " & lowestfreenum
Else
' Create new slot:
trackcount = trackcount + 1
' Increase size of both arrays:
ReDim Preserve childtrack(1 To trackcount)
ReDim Preserve child_array(1 To childcount)
' Load a new menu item for each child form
' under the menu control mnu_sim(0):
Load mnu_sim(trackcount)
' Set a new caption for the new menu item and supply access key:
' Turn the following two lines into one, single line:
mnu_sim(trackcount).Caption =
"Show Only Child Form Number &" & trackcount
' Mark this slot as loaded:
childtrack(trackcount) = True
' Set the tag equal to the childcount
' to allow tracking of self:
child_array(trackcount).Tag = trackcount
' set unique caption for each child form
' this causes implicit load and shows child
child_array(trackcount).Caption = "Child Form Number " & trackcount
End If
End Sub
Sub mnu_showall_Click ()
' Place simulated background form at the bottom of the Z order:
backsim.ZOrder 1
' Bring all the loaded child forms to the top of the Z order in
' succession:
For i = 1 To trackcount
If childtrack(i) Then
If Not child_array(i).Enabled Then child_array(i).Enabled = True
child_array(i).ZOrder 0
child_array(i).Caption = child_array(i).Caption
End If
Next i
Exclusive = False
End Sub
Sub mnu_sim_Click (index As Integer)
' Special case: if the arrange method has tiled the child windows,
' reset arrangement to cascade to get ZOrder method to work:
If tiledflag Then
MDIform1.Arrange 0 ' cascade
tiledflag = False
End If
If index = 0 Then
' User wants to clear all children from MDI form
' but does not want to unload them:
backsim.ZOrder 0
' Disable minimized form to avoid system menu popup:
For i = 1 To trackcount 'UBound(childtrack)
If childtrack(i) Then
If child_array(i).WindowState = 1 Then
child_array(i).Enabled = False
End If
End If
Next i
Else
' Bring the simulated background to the top
' of the Z order to hide all other children:
backsim.ZOrder 0
' Disable minimized form to avoid system menu popup:
For i = 1 To UBound(childtrack)
If childtrack(i) Then
If child_array(i).WindowState = 1 Then
child_array(i).Enabled = False
End If
End If
Next i
' Bring desired child form to the top:
child_array(index).ZOrder 0
child_array(index).Enabled = True
child_array(index).Caption = child_array(index).Caption
child_array(index).SetFocus
' Set flag for QueryUnload event of child form
' to avoid a repaint over the next child form in
' Z order if unload current "only" child:
Exclusive = True
End If
End Sub
Sub mnu_tileh_Click ()
backsim.ZOrder 1
MDIform1.Arrange 1 ' Tile horizontal.
tiledflag = 1
End Sub
Sub mnu_tilev_Click ()
backsim.ZOrder 1
MDIform1.Arrange 2 ' Tile vertical.
tiledflag = 2
End Sub
Sub mnu_unloadall_Click ()
' Unload all child forms marked
' as loaded in childtrack array:
For i = 1 To trackcount ' UBound(childtrack)
If childtrack(i) Then
Unload child_array(i)
End If
Next i
' Reset counters:
trackcount = 0
childcount = 0
End Sub
' The following includes the form and control descriptions as well
' as necessary Function and Sub procedures. Place the code in a
' single text file called BACK_SIM.FRM, so you can load it as a form
' in Visual Basic.
VERSION 2.00
Begin Form backsim
BackColor = &H00C0C0C0&
BorderStyle = 0 'None
ClientHeight = 4776
ClientLeft = 1632
ClientTop = 1644
ClientWidth = 7368
ControlBox = 0 'False
Enabled = 0 'False
Height = 5196
Left = 1584
LinkTopic = "Form2"
MaxButton = 0 'False
MDIChild = -1 'True
MinButton = 0 'False
ScaleHeight = 4776
ScaleWidth = 7368
Tag = "BackSim"
Top = 1272
Width = 7464
End
Sub Form_Load ()
' Set the backcolor property to match
' whatever system color setting the user has set
' for the Background color of multiple document
' interface (MDI) applications:
Me.BackColor = GetSysColor(COLOR_APPWORKSPACE)
End Sub
' The following includes the form and control description as well as
' necessary Function and Sub procedures. Place the code in a single text
' file called SIMCHILD.FRM, so you can load it as a form in Visual Basic.
VERSION 2.00
Begin Form ftemplate
Caption = "ftemplate"
ClientHeight = 6300
ClientLeft = 1116
ClientTop = 1224
ClientWidth = 7368
Height = 6720
Left = 1068
LinkTopic = "Form3"
MDIChild = -1 'True
ScaleHeight = 6300
ScaleWidth = 7368
Top = 852
Width = 7464
End
Sub Form_QueryUnload (cancel As Integer, unloadmode As Integer)
' Remove menu item pointing to Me:
Unload mdiform1.mnu_sim(Val(Me.Tag))
' Mark my slot as unloaded:
childtrack(Val(Me.Tag)) = False
' Decrement total childcount:
childcount = childcount - 1
' If this form was the only child form visible
' at the time of unload, put background
' form the top of the z order:
If Exclusive Then
' Must enable background form temporarily
' so that it will be the next in the Z order
' after the unload. This avoids a repaint over
' the previous child in the Z order.
backsim.Enabled = True
backsim.ZOrder 0
backsim.Enabled = False
Exclusive = False
End If
End Sub
Sub Form_Resize ()
' Keep minimized children visible by
' setting the ZOrder explicitly:
If Me.WindowState = 1 Then
Me.ZOrder 0
' Force repaint of caption:
Me.Caption = Me.Caption
End If
End Sub
Global child_array() As New ftemplate
Global childtrack() As Integer
Global childcount As Integer, trackcount As Integer
Global lowestfreenum As Integer, i As Integer
Global Exclusive As Integer, tiledflag As Integer
Declare Function GetSysColor Lib "User" (ByVal nIndex%) As Long
Global Const COLOR_APPWORKSPACE = 12
Additional query words: 3.00
Keywords : kbcode PrgOptTips
Version : 3.00
Platform : WINDOWS
Issue type :
Last Reviewed: June 9, 1999