Visual Basic is an enigma. Pitched at inexperienced programmers, its
evolution as a programming language has been slow, yet each new
version ships with an overwhelming array of new plug-in technology
for data access and component building. On the one hand we're
expected to build increasingly sophisticated distributed
applications, but on the other hand we're not allowed to get too
technical. VB's rudimentary code editor pegs it as a tool for the
new breed of tinkertoy developer, yet language features aimed at
getting novices started simply get in the way of developers who have
accumulated enough experience to do anything useful. One such
example is the behaviour of forms, which we'll look at in detail
here.
Forms are essentially classes - 'essentially', because they're also
a little bit more than classes. We can mostly use a form anywhere we
can use a class (see Chapter 1 for some exceptions), but obviously a
form can have visible attributes too. It doesn't have to be visible:
for example, we might use a form in place of a regular class module
because we need a class that uses a timer control. When working with
forms we also need to appreciate that the visual part of a form can
be in a 'loaded' or 'unloaded' state; as we'll see, most of the
problems with forms revolve around these two states.
If, as is the case with classes, we were compelled to define
instances of our forms before using them, one of the most confusing
form issues would cease to be an issue. This would mean that we'd
always need code like this to use any form in our program:
Dim oMyForm As New Form1
oMyForm.Show vbModal
Unfortunately, whether or not we define any instances of a form,
Visual Basic creates one for us. We reference this object via an
implicitly-defined global variable that has the same name as the
class. That last sentence deserves to be printed in bold in Chapter
1 (or perhaps Chapter 6!) of every Visual Basic book and to be
taught on the first morning of every Visual Basic training course,
since it explains unambiguously why we can use the identifier
'Form1' to mean two entirely different things in two different
contexts:
Form1.Show ' Form1 is an object name
Dim oNewForm As New Form1 ' Form1 is a class name
Sadly, VB books and programming courses almost inevitably teach
programmers to use VB's implicitly-defined forms without explaining
what's going on. Creating explicit instances of forms is usually
taught as a minor 'advanced' topic, to be glossed over hurriedly
when MDI applications are considered. The unfortunate consequence is
that many intermediate and 'advanced' VB programmers just don't
understand what they're doing. You can program without ever touching
VB's implicitly-defined forms, and I suggest that you do (see
Chapter 1 if you need to be persuaded).
To have a full understanding of forms we need to know about the
different states a form can exist in. To do that, first we need to
look at the different ways in which class instances are created.
With classes things are relatively simple: our class instance
(object) either exists or it doesn't. When it comes into existence,
the Class_Initialize event handler runs, and when it is destroyed,
the Class_Terminate event handler runs. There's also an issue of
when the object is actually created, which differs according to how
we write the code:
Dim oMyObj As CMyClass ' (1)
Set oMyObj = New CMyClass ' (2)
oMyObj.SomeProperty = 2 ' (3)
or
Dim oMyObj as New CMyClass ' (4)
oMyObj.SomeProperty = 2 ' (5)
In the first example, the object is actually created at line (2). By
'actually created' we mean that the object has memory allocated and
its Class_Initialize event handler runs. This is fairly intuitive,
as Line (1) is a simple variable definition and not an executable
statement. Most importantly, we can say unambiguously that the
object has been created and initialized by line (3) - effectively we
can consider the Set statement as a call to the Class_Initialize
event handler.
By contrast, in the second example the object isn't created until
line (5), which is the first reference to any property or method -
most certainly NOT intuitive! In a real application, of course, the
first reference may be pages away from the variable definition and
such references are very likely to be added and deleted throughout
the development of the program. As a result, there is no line we can
point to and say with certainty that it creates the object. This may
。。。。。。。。。
a Form_Load
event. (To convince yourself of this, check out the following
example program.)
Example Code:
Auto-instantiated Form
For this example you need two forms. Form1 has two command
buttons, and you should paste the following code into the
forms. The buttons load and unload an instance of Form2, which
clicking on Form1's background displays Form2's caption. The
beeps just tell you when the Form_Load and Form_Unload events
are executed.
Note that the the variable f, an instance of Form2, is NOT
auto-instantiated - this object remains in existence during
the lifetime of Form1. Despite this, the visual part of Form2
(an anonymous object created from the Form interface) IS
auto-instantiated, since we can manipulate it (though 'it' is
really a new object) even after the form is unloaded.
Form1
Private f As Form2
Private Sub Command1_Click()
Load f
f.Caption = "hello"
f.Show
End Sub
Private Sub Command2_Click()
Unload f
End Sub
Private Sub Form_Click()
MsgBox f.Caption
End Sub
Private Sub Form_Load()
Set f = New Form2
End Sub
。。。。。。。。。。。。。
quality software.