Lab 14
- We have surveyed how to write form and code
modules (with special attention to arrays and strings for storing data and
to writing our own Sub and Function procedures to break code into small,
focused pieces so that loop can be written compactly), we have reviewed
the toolbox controls and become familiar with many of the events that the
controls recognize and the process of coding event procedures. In this lab
we turn to the organization of the GUI at run-time (forms and frames being
the organizers at design time). We have built several forms for some of
our projects, but we had to execute the forms one at a time by setting the
project property to the form to be run when we ran the project. Thus our
projects have utilized a SDI or single document interface. Chapter 11
introduces the MDI form that is
visually distinctive from the forms we have been using in what two
characteristics?
The child window, or MDI form,
can never be moved outside of the parent window. Also, the title bar, (1)icon, and
name are different plus (2) the background color
of the MDI is darker to indicate that it is a child window.
NOTEPAD AND FORMS
MDI can have multiple
documents open at the same time.
The child window cannot be moved outside the parent.
The MDI form has a parent and
a child window where a SDI form has only one window. With a MDI form you can
have many windows open at once.
MDI can
have multiple files open at the same time.
MDI applications have child and parent
structure, with the parent window contain the child windows.
- A
MDI form is added to a project from the Project menu. A project may have
up to one MDI forms. ONE A project can only contain 1 MDI
form. One one (1)_
- A
"standard" form can be converted into a child form by changing
the value of its MDIChild property. MDI MDIChild
property to True MDIChild
MDIChild
- Create
a new project, add a second form, then add a MDI form. Run the project.
What can the user do? Render a
window inside a window.
THE USER CAN MINIMIZE THE FORMS WITHIN THE MDI ENVOIRMENT
The user can move the child around in
the MDI form, minimize, maximize and close the child window without
closing the MDI form. When the user maximizes the form window the name of
the form is placed in parenthesis on the MDI forms title bar. When the
user closes the MDI form, the project stops running.
The user can maximize or
minimize the child form. The child form can be closed. The child form
cannot be moved outside the parent window. When the parent is closed it
closes the application, but when the child is closed it does not close the
application.
You
can move the child window around in the MDIForm, minimize and maximize the
child window, and close the child window.
The MDIForm will still be open after you close the child window,
but when you close the MDIForm window, the project stops running. When you maximize the child window, the
title bar in the MDIForm changes to include the title of the child
window. You cannot move the child
window outside the parent window.
When you try, the parent form (MDIForm) adds scroll bars.ßthe parent
makes the area for the child BIGGER (inside the parent frame) if you want to move the child past the
current edge of the the parent.
- Check
the startup object in the project properties and change it to a different
form. What difference does it make? Different form loads and MDI
form. The title changes, etc.
WHICH EVER FORM IS SELECTED TO BE
EXECUTED THAT TITLE WOULD GO TO THE MDI’S TITLE BAR
The difference changing the startup
properties makes is which child form opens in the MDI form. If you have
the MDI form selected to start, then a blank form opens with no child.
When you set it to start up form 2 it
makes no difference when it is set to startup the MDI form it opens with
no child form.
For
example, if you have Form 1 selected, then when you run it, the MDIForm is
parent, and the Form1 is opened within it. If you have Form 2 selected, when you run it, the MDIForm is
opened with Form2 inside of it. On
the other hand, when you have the MDIForm selected as the form to run, you
get a blank MDIForm with no child window opened within it.
- Place
some controls on each of your three forms. How are you restricted? Controls without the align property
cannot be added to MDI form. In
essence all controls except PictureBox can only be placed on the standard
forms or child forms.
THE REGULAR FORMS CAN HAVE BUTTONS,
BUT THE MDI HAS TO HAVE CEARTAIN ALIGINMENTS.
There are only three controls that can
be placed on the MDI form. These are the picture box, timer, and data
controls. These controls are either not visible at run time or they
contain the Align property. The other controls are restricted and an error
message appears saying: Controls without the align property cannot be
placed directly on the MDI form.
You cannot place controls
without the align property directly on the MDI form or controls not
visible at run time.
The
MDI forms can only contain controls that have an align property (like
PictureBox), or controls that are not visible at run-time (Timer
control). The only controls the MDI
Form can contain from the control
bar allowed are: data, picture and
timer.
- What
does the PictureBox offer in the way of removing the restriction? The Picture Box allows you to place
controls within its boundaries.
Basically, if you add a PictureBox to the MDI form you can then
place your controls inside the PictureBox and thus on the MDI form.
THE PICTURE BOX HAS ALIGINMENT
PROPERTIES THAT TAKE AWAY THE RESTRICTIONS.
The picture box allows the user to use
it as a container and indirectly places the controls inside it.
It can be used as a container to hold
the controls that cannot be placed directly on the MDI parent form.
The PictureBox can be used as a
“container,” which allows the programmer to indirectly use controls that
are not allowed to be placed directly on the MDI parent form.
- Place
a button in a picture box on the MDI form and then run with form1 as the
start object. What do you observe about the behavior of form1? Adjusts it size to fit in a newly defined area. The PictureBox further limits the size
that form1 can take on.
IT CONTAINS THE PICTURE BOX AND
DOES NOT MAXIMIZE TO FIT THE PARENT WINDOW.
Form one is placed below the picturebox
on the MDIform. The picturebox acts as a frame would on a web page. If you
maximize the form1, it only maximizes to the bottom of the picturebox
container and the MDI form takes the Form1 name into its title bar.
It cannot cover the picture box on the MDI
parent form.
It
is contained outside of the PictureBox in the MDI form. It is resized to allow for the MDI
control to be its full size. The
PictureBox acts in much the same way as a frame would on a web page. When you maximize Form1, Form1 only
maximizes to include the area not used by the PictureBox, and it changes
the title bar property of the MDI form to include the name of Form1.
- Some
form must be loaded first, and it can then load other forms. Place a
button on each of your three forms. Label the button on Form1 "load
form 2" . Label the button on the Midi form "load form 1".
When either of these buttons are pressed, Call load for the specified form
and then call that form’s show property. The button on Form2 should print
on form1 "printing from form 2" every time it is pressed. Insert
the project (*.vbp) file here.
Type=Exe
Form=Qst10b.frm
Reference=*\G{00020430-0000-0000-C000
000000000046}#2.0#0#C:\WINNT\System32\STDOLE2.TLB#OLE Automation
Form=Qst10a.frm
Form=Lab14.frm
Startup="MDIForm1"
HelpFile=""
Command32=""
Name="Project1"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionCompanyName="UALR"
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1
- The
Picture box is aligned top by default. Change its alignment to Right and
run the project and observe what is different (record your observations
here). The PictueBox increased
in size to fill the MDI window and would not allow for the loading of
Form1 or Form2. However, if you
increase the size of the MDI, window before you run, you can see that the PicturBox runs the
length of the rightside of the MDI and the forms are loaded into the left
column. The major problem is
getting the forms to fit within the windows.
COMPARED TO TOP AND BOTTOM, THE
LEFT ALIGIN PROPERTY FILLS THE WHOLE SCREEN.
The picture box was on the far right
side of the screen and when forms 1 and 2 were loaded, they became longer
and skinner to load in the remaining part of the MDI form.
Align right it takes up the whole right
side.
It aligns the PictureBox to the right,
but it also makes it larger and increases the height from top of form to
bottom. It then loads forms to the
left of it. The forms are resized
as well. The width is decreased
and the height is increased.
You
cannot Print to the MDIform, but you CAN print to its picture box. Do so when
form2’s button is pressed. MDIForm1.Picture1.Print “printing from Form 2”
Private Sub Command1_Click()
MDIForm1.Picture1.Print "Printing from form 2"
End Sub
MDIForm1.Picture1.Print
"printing from form 2"
Private
Sub Command1_Click()
MDIForm1.Picture1.Print
"Printing from Form 2"
End Sub
- Add
two buttons to the MDIform, one labeled Tile and the the other labeled
Cascade. When either is pressed, invoke the Arrange method with the proper
argument and explain what happens here.
Cascade
layers the forms while Tile fills the area of the MDI form with how many ever
forms you have. You can either use tile
horizonal(1) or tile vertical(2).
THE WINDOWS BECOME ARRANGED IN AN ORDER, BUT WHEN
TILE IS PRESSED THE WINDOWS LINE UP VERTICALLY.
After the forms are loaded, when you press
tile, form1 and form2 are placed in the empty space on the MDI form. Form 1
above form 2. They are the same size and shape. When you press cascade, the
forms are placed with form2 a little below form1, but on top of it.
The cascade button stacks the windows on top of
each other and the tile button fills up the form with the 2 windows next to
each other.
When
the Tile button is pressed, it fills up the area equally with form 1 and
2. In other words, they are
“tiled.” On the other hand, when
Cascade is pressed, it cascades the windows on top of each other, aligning them
so that you can see each one’s form title bar.
12. Modify the project to that the button to load a form
also unloads the other other form. Insert the *.frm file for form2 here.
Option
Explicit
Private Sub Command1_Click()
Call Load(Form2)
Call Unload(Form1)
Call Form2.Show
End Sub
You had TWO load buttons, one for form1 and one for
form2. This is the form2 button altered
correctly.
VERSION 5.00
Begin VB.MDIForm MDIForm1 ßbutton loads form1 inside PictureBox
BackColor =
&H8000000C&
Caption =
"MDIForm1"
ClientHeight = 8025
ClientLeft =
45
ClientTop =
270
ClientWidth = 7935
LinkTopic =
"MDIForm1"
StartUpPosition
= 3
'Windows Default
Begin
VB.PictureBox Picture1 ß
PictureBox defined
Align =
1 'Align Top
Height =
1215
Left = 0
ScaleHeight = 1155
ScaleWidth = 7875
TabIndex = 0
Top = 0
Width =
7935
Begin
VB.CommandButton Command3 ß
wanted “Load form”
Caption = "UNLOAD FORM"
Height = 615
Left = 360
TabIndex = 3
Top = 480
Width =
2175
End
Begin
VB.CommandButton Command2
Caption = "TILE"
Height = 615
Left = 5160
TabIndex = 2
Top = 480
Width = 2415
End
Begin
VB.CommandButton Command1
Caption = "CASCADE"
Height = 615
Left = 2640
TabIndex = 1
Top = 480
Width = 2295
End Button
End PictureBox
End MDIform1
Attribute VB_Name = "MDIForm1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Sub Command1_Click()
Arrange (0) ßCascade
End Sub
Private Sub Command2_Click()
Arrange (1) ßTile
End Sub
Private Sub Command3_Click()
Call load(Form1)
Call Unload(Form2)
Form1.show
End
Sub
- MDI
forms serve as a frame to hold multiple windows and its Arrange method
determines how the child windows appear in the frame. The MDIframe may
also contain other controls (we could have a second PictureBox). However,
we can have multiple forms displayed on the screen without nesting them
insider a MDIform. Add a third form to the project and use the Form Layout
window to position it in the upper right corner while the MDIform1 is
positioned with its upper left corner toward the middle of the screen.
Place a button on form3 the loads and shows the MDIform and set form3 as
the load object. Manipulate both forms to the extent that you can and then
explain how form3 and the MDIform interact when the project is run.
As long as you use the Call ___.Show, the MDI form
will appear wherever you have told the layout to load it to. However, you cannot set the positioning for
the forms that render in the MDI window.
The user is only allowed to manipulate the external forms, i.e. standard
forms and MDI forms.
FORM THREE CALLS THE MDI FORM TO BE PROMPTED BUT
BOTH ARE IN DIFFERENT POSITIONS. SO FORM 3 DOES NOT GO ON TO MDI FORM.
When the project runs, form 3 is displayed
in the Right hand corner. You click on the button on from 3 and the MDI form is
displayed in the Left hand corner. They interact separately. You can click and
drag each, and which ever one you click on has the focus. The project does not
end until you close BOTH windows.
When the load form 3 button is pressed it puts
the focus on form 3 and when the button is pressed to load the MDI form the
focus changes to the MDI form.
When the
project is run, form3 appears in the upper righthand corner. When you press its button, the MDIForm
appears in the middle of the screen.
Both the MDIForm and Form3 are shown running in the bottom task bar, and
each can be minimized, maximized or closed separately. If you maximize the windows, whichever form
has the focus is the one brought to the front.
You can resize the boxes separately and click on either to obtain
focus. You can also click and drag the
forms over each other, with the one you are dragging remaining on top, since it
has the focus.
- The
remaining entry on the project properties start object drop-down is Sub
Main. This procedure must be written and stored in a *.bas module because
it is NOT connected to a form. It is explained on page 472 and illustarted
on page 473. How is it like and unlike a form_Load event procedure ? The form_Load is used to load
information automatically to a form when the form is activated. However, when many forms are used, the
Sub Main is used to make sure that VB starts with the correct form. Thus, the form_Load is used to “upload”
information to a form, while Sub Main is used to load the proper forms in
the proper order, so to speak.
IT IS LIKE A PROCEDURE BY USING
ARGUMENTS, BUT DOES NOT NEED AN TERMINATION.
There is not a GUI in the sub main. Any
code in the *.bas associated with the sub main would be executed
prior to any GUI loading.
With the Main Procedure does not have to
have a GUI associated with it runs independent of the GUI and can start up
many forms on run. It is the same in respect that the form is loaded into
memory and is called to use.
The
main procedure has no GUI associated with it. Any code associated with the main procedure would be
executed prior to any GUI loading.
- Forms
have a title and we have exercised the minimize and maximize buttons at
the right end of the title bar, but we have only used the close button to
end the program. In 14 we should have noticed that the close button only
ended the program because there was no other form being displayed. The
event procedure QueryUnload is called when the close button is pressed,
and if no code has been provided, the form Unload event is processed.
Pages 472 to 475 illustrate writing code for the QueryUnload, code which
uses the MsgBox with a Yes/No option. The example deals with four
different frames. How many are visible at once? For each visible frame,
what happens when its close button is pressed (you may have to run the
author’s code to find the answer, but if so, you want to either remark out
the set statements in frmStarter or find the path to the *.gif files
)? Only one form is visible at
a time and each time any of the close buttons are hit, a ß not so. There are 4 forms and two are visible at a time. MsgBox appears that asks if you are sure you want to exit and
returns a 0 or 1 depending on whether you select Yes or No.
YOU ARE ASKED BY THE COMPLIER IF
YOU WOULD LIKE TO SAVE CHANGES OR EXIT THE PROGRAM.
Only one frame is visible at a time.
You must close the picture form, before you can click on the Starter form
and try to open another picture form. When you close the picture forms, it
brings the focus back to the Starter form. When you close the Starter
form, it displays a message asking if you are sure you want to close.
Only one is visible at a time. When the
close button is pressed you can the close the MDI form and it asks if you
are sure you want to exit. The frame just closes when its close button is
pressed.
One
frame is visible at a time. When
you close the individual frames, they just close, but when you try to
close the frame with the 3 buttons on it, it asks you if you are sure you
want to exit and yes or no.
- Explain
why the author used an array of images in fir. 11.16. Would the program
work the same if all of the buttons said
frmForm1.imageImage.Picture=….
Call frmForm1.Show(….
That is, if ONLY ONE FRAME WERE USED?
Yes, all the array values are defined and then there are no step
throughs in any of the code.
Therefore, the author only needs to indicate the name of the value
he wants placed where.
ONLY ONE FRAME WERE USED? I DON’T THINK
IT WOULD WORK BECAUSE YOU ONLY HAVE ONE FRAME, AND TO USE THE CALL FRM
METHOD WOULD WORK, BUT IF YOU HAVE ONLY ONE FRAME WHY USE IT. ßbut
frames only differ by the picture you load into them!
He used an array to hold the different
pictures, however, he could do this using one form. The title bar is the
only thing that would be affected. It would display form1, unless the
buttons were coded to change the title in the title bar.
The array holds the 3 different pictures
but the author did not need to use three different forms to display the
pictures. But yes it will work either way.
He
used an array to hold the different pictures, but you could do it all
using one form. The title bar on
the form would have to be changed each time.
- When
Windows Explorer is used to click on a *.frm file VB60 is called and the
form file is added to a default project and executed. However, VB60 can be
set to make an *.exe file that will execute in Windows without VB (except
that it may still need the *.dll file). This is discussed in 11.10, EXCEPT
that your demo version of VB60 does not have this capability. Write and
execute the program specified in exercise 11.10. Although this is just a
"busy" loop and it is not expecting the user to do anything
else, if it takes a long time we might get tired and like to stop (there
should be a start and stop button on the interface and a textbox into
which the 200 million or some like number can be input before the START
button is pressed, and there should be a label in which the elapse time is
displayed). Therefore you will want to use the DoEvents method as
illustrated in fig. 11.20 and discussed on p. 479.
Option Explicit
Private Sub Command1_Click()
Dim x As Long, Time As Long, Counter As Long
Time = Timer()ßa
function like NOW that returns the clock value
For x = 200000000 To 0 Step –1
Text1.Text = x
DoEventsßwithout this the Stop button won’t work
Next x
Counter = Timer() – Time
Label1.Caption = Counter
End Sub
Private Sub
Command2_Click()
End
End Sub