Home All Groups Group Topic Archive Search About

When and where do I do Set m_FormVar = Nothing?

Author
3 Jun 2009 3:50 PM
MM
Suppose I have:

Private WithEvents m_Whatever As cMouseTrack

in the form's declarations section.

I'd like to tidy up afterwards with:

Set m_Whatever = Nothing

Do I place that in Form_Unload or in Form_Terminate?

MM

Author
3 Jun 2009 7:47 PM
Karl E. Peterson
MM wrote:
> Suppose I have:
>
> Private WithEvents m_Whatever As cMouseTrack
>
> in the form's declarations section.
>
> I'd like to tidy up afterwards with:
>
> Set m_Whatever = Nothing
>
> Do I place that in Form_Unload or in Form_Terminate?

Depends.  Form_Terminate would be the likely choice, but there may be some reason
you'd prefer to see it in Form_Load.  If it's not needed after Unload, no harm
either way.
--
..NET: It's About Trust!
http://vfred.mvps.org
Author
3 Jun 2009 7:51 PM
Ralph
Show quote Hide quote
"MM" <kylix***@yahoo.co.uk> wrote in message
news:rq6d251opfah4i32m38dg5513ubs0fha8u@4ax.com...
> Suppose I have:
>
> Private WithEvents m_Whatever As cMouseTrack
>
> in the form's declarations section.
>
> I'd like to tidy up afterwards with:
>
> Set m_Whatever = Nothing
>
> Do I place that in Form_Unload or in Form_Terminate?
>
> MM

Forms have various states of "being". It is possible to have a Form unloaded
and yet maintain its private data. The private data doesn't disappear until
the Form is unloaded and the reference is explicitly or implicity set to
Nothing. The preservation of private data can be a feature, but usually it
is an disaster waiting to happen, if you don't realize it is there. <g>

Form Unload is called whenever a form is unloaded (explicity or implicitly).
Form Terminate is called whenever all references to the Form is destroyed
for good.

So the question is - do you want m_Whatever to linger? Or does your design
assume things are gone when the form is unloaded?

-ralph
Author
4 Jun 2009 6:44 AM
MM
Show quote Hide quote
On Wed, 3 Jun 2009 14:51:12 -0500, "Ralph" <nt_consultin***@yahoo.com>
wrote:

>
>"MM" <kylix***@yahoo.co.uk> wrote in message
>news:rq6d251opfah4i32m38dg5513ubs0fha8u@4ax.com...
>> Suppose I have:
>>
>> Private WithEvents m_Whatever As cMouseTrack
>>
>> in the form's declarations section.
>>
>> I'd like to tidy up afterwards with:
>>
>> Set m_Whatever = Nothing
>>
>> Do I place that in Form_Unload or in Form_Terminate?
>>
>> MM
>
>Forms have various states of "being". It is possible to have a Form unloaded
>and yet maintain its private data. The private data doesn't disappear until
>the Form is unloaded and the reference is explicitly or implicity set to
>Nothing. The preservation of private data can be a feature, but usually it
>is an disaster waiting to happen, if you don't realize it is there. <g>
>
>Form Unload is called whenever a form is unloaded (explicity or implicitly).
>Form Terminate is called whenever all references to the Form is destroyed
>for good.
>
>So the question is - do you want m_Whatever to linger? Or does your design
>assume things are gone when the form is unloaded?
>
>-ralph
>

The reason I'm taking a closer look is that I have started to
experience a GPF in the VB6 design environment in either USER.EXE or
KRNL386.EXE after the following sequence:

Load VB6 application, run it, exit the app but keep design environment
loaded.

Run Eudora Mail.

GPF in VB6 !!

This is a consistent fault. I can reproduce it every time. The GPF
happens immediately Eudora is loaded.

Up until now I have been somewhat lackadaisical with Set ??? = Nothing
after use, so I thought that one area to exclude while narrowing down
the cause of the GPF would be to tidy up object vars.

Strange thing is, the GPF occurs ONLY with the combination VB6 design
env + my app + Eudora Mail (which is the old, sponsored version 5.1).
I've tried to promote the GPF by loading variously Word, Paint Shop
Pro, Firefox, Ahead Nero, or Finale Notepad, but none of these causes
the GPF. As soon as I load Eudora, however, the GPF occurs.

The GPF does NOT occur if I run my application's compiled .exe, then
load Eudora. Only the combination as described above (environment + my
app runs then is exited + run Eudora = boom!).

BTW, it doesn't happen with any other VB6 app in the env, but only
with this current app that uses several object vars pointing to
various class modules. The class modules are: clsWaitableTimer.cls,
cMouseTrack.cls, cTile.cls. cTile.cls is the most recent addition.

If careful management of the object vars doesn't fix the problem I
shall have to start commenting out the classes in turn to see if I can
pin down the cause, but that could be a longwinded process.

Alternatively, I do have backups of the past 20 versions, and the GPF
didn't used to happen, so it must be being caused by a recent addition
or modification.

MM
Author
4 Jun 2009 9:27 PM
Karl E. Peterson
You're leaving something dangling.  I'd have to guess it's the waitable timer.  Are
there any other external (COM) libraries you're using?  With the EXE, Windows will
terminate everything as the process ends.  But in the IDE, the process *is* the IDE,
so that doesn't happen.
--
..NET: It's About Trust!
http://vfred.mvps.org



MM wrote:
Show quoteHide quote
> On Wed, 3 Jun 2009 14:51:12 -0500, "Ralph" <nt_consultin***@yahoo.com>
> wrote:
>
>>
>>"MM" <kylix***@yahoo.co.uk> wrote in message
>>news:rq6d251opfah4i32m38dg5513ubs0fha8u@4ax.com...
>>> Suppose I have:
>>>
>>> Private WithEvents m_Whatever As cMouseTrack
>>>
>>> in the form's declarations section.
>>>
>>> I'd like to tidy up afterwards with:
>>>
>>> Set m_Whatever = Nothing
>>>
>>> Do I place that in Form_Unload or in Form_Terminate?
>>>
>>> MM
>>
>>Forms have various states of "being". It is possible to have a Form unloaded
>>and yet maintain its private data. The private data doesn't disappear until
>>the Form is unloaded and the reference is explicitly or implicity set to
>>Nothing. The preservation of private data can be a feature, but usually it
>>is an disaster waiting to happen, if you don't realize it is there. <g>
>>
>>Form Unload is called whenever a form is unloaded (explicity or implicitly).
>>Form Terminate is called whenever all references to the Form is destroyed
>>for good.
>>
>>So the question is - do you want m_Whatever to linger? Or does your design
>>assume things are gone when the form is unloaded?
>>
>>-ralph
>>
>
> The reason I'm taking a closer look is that I have started to
> experience a GPF in the VB6 design environment in either USER.EXE or
> KRNL386.EXE after the following sequence:
>
> Load VB6 application, run it, exit the app but keep design environment
> loaded.
>
> Run Eudora Mail.
>
> GPF in VB6 !!
>
> This is a consistent fault. I can reproduce it every time. The GPF
> happens immediately Eudora is loaded.
>
> Up until now I have been somewhat lackadaisical with Set ??? = Nothing
> after use, so I thought that one area to exclude while narrowing down
> the cause of the GPF would be to tidy up object vars.
>
> Strange thing is, the GPF occurs ONLY with the combination VB6 design
> env + my app + Eudora Mail (which is the old, sponsored version 5.1).
> I've tried to promote the GPF by loading variously Word, Paint Shop
> Pro, Firefox, Ahead Nero, or Finale Notepad, but none of these causes
> the GPF. As soon as I load Eudora, however, the GPF occurs.
>
> The GPF does NOT occur if I run my application's compiled .exe, then
> load Eudora. Only the combination as described above (environment + my
> app runs then is exited + run Eudora = boom!).
>
> BTW, it doesn't happen with any other VB6 app in the env, but only
> with this current app that uses several object vars pointing to
> various class modules. The class modules are: clsWaitableTimer.cls,
> cMouseTrack.cls, cTile.cls. cTile.cls is the most recent addition.
>
> If careful management of the object vars doesn't fix the problem I
> shall have to start commenting out the classes in turn to see if I can
> pin down the cause, but that could be a longwinded process.
>
> Alternatively, I do have backups of the past 20 versions, and the GPF
> didn't used to happen, so it must be being caused by a recent addition
> or modification.
>
> MM
Author
4 Jun 2009 11:36 PM
MM
On Thu, 4 Jun 2009 14:27:41 -0700, "Karl E. Peterson"
<k***@exmvps.org> wrote:

>You're leaving something dangling.  I'd have to guess it's the waitable timer.  Are
>there any other external (COM) libraries you're using?  With the EXE, Windows will
>terminate everything as the process ends.  But in the IDE, the process *is* the IDE,
>so that doesn't happen.

In the meantime (see my later new topic) I found the cause to be
calling the HtmlHelp API, which, I am now aware, is a known problem.

That said, I am going to pay far greater attention to how objects are
created and destroyed. I still don't understand the significance of
the Form_Terminate event properly, though. Wish there was a lengthy
description of all these more obscure events! Initialize is another
one. And Form_Activate yet another! Is it me, or did Microsoft make up
the design as it went along? Not being an OOP person, I have spent all
these years religiously sticking with Form_Load and _Unload, but now,
with so many free third-party user controls available from enthusiasts
just by whacking a .cls into one's project, I cannot ignore the
ramifications any longer.

MM
Author
5 Jun 2009 12:22 AM
Karl E. Peterson
MM wrote:
> In the meantime (see my later new topic) I found the cause to be
> calling the HtmlHelp API, which, I am now aware, is a known problem.

Good to hear you found it.

> That said, I am going to pay far greater attention to how objects are
> created and destroyed. I still don't understand the significance of
> the Form_Terminate event properly, though. Wish there was a lengthy
> description of all these more obscure events! Initialize is another
> one. And Form_Activate yet another! Is it me, or did Microsoft make up
> the design as it went along?

It's you. <g>

Forms are classes with a UI.  Just like any other class, they can be created and
destroyed *without* the UI, although that's not normally done.  But it's a critical
concept.  Initialize and Terminate mean exactly the same thing in forms as they do
in any class.  Load and Unload are similar, but they apply only to the UI for the
class instance.  Now, it so happens that these are all rigged up such that anyone
who still programs like it was VB1 won't be at all confused.  But the rest of this
really came on board (albeit, invisibly) at VB2.  In fact, forms were the first
classes available in VB!

> Not being an OOP person, I have spent all
> these years religiously sticking with Form_Load and _Unload, but now,
> with so many free third-party user controls available from enthusiasts
> just by whacking a .cls into one's project, I cannot ignore the
> ramifications any longer.

They, or rather the possibilities they represent, are mind-boggling once it truly
hits you.  Try this:

Module1.bas:

   Option Explicit

   Public Sub Main()
      Dim frm As Form1
      Dim i As Long

      Set frm = New Form1
      For i = 1 To 3
         frm.Show vbModal
      Next i
   End Sub

Form1.frm

   Option Explicit

   Private m_Static As Long

   Private Sub Form_Load()
      m_Static = m_Static + 1
      Me.Caption = "i = " & m_Static
   End Sub

   Private Sub Form_Terminate()
      MsgBox "All Done!"
   End Sub

Try to predict what will happen, before it does.  Then, try to figure out why you
didn't predict correctly.  (Hint: The reason is, the form's class instance is
persistent.)
--
..NET: It's About Trust!
http://vfred.mvps.org
Author
5 Jun 2009 12:04 PM
Larry Serflaten
"MM" <kylix***@yahoo.co.uk> wrote

> That said, I am going to pay far greater attention to how objects are
> created and destroyed. I still don't understand the significance of
> the Form_Terminate event properly, though. Wish there was a lengthy
> description of all these more obscure events! Initialize is another
> one. And Form_Activate yet another!

I don't see where the problem is.  VB loads modules on demand, so if
you never call up an object, it doesn't get loaded into memory.  When
you do call one up, it first has to initialize the memory (variables set to 0
and all that) and they give you a chance to act on that event too.  When
it is no longer needed, it is removed from memory, appropreatly called
terminated, and you can act on that event also.

If the object you call up has a User Interface (like Forms do) that is a
seperate entity from the plain jane code module that classes have.  When
that is brought into memory it goes through another initialization phase
(UI properties, control locations, etc) and you get an event to use when
that happens.  Likewise when the UI is tearing down, (unloading) you
get an event there as well.

You can have the code module present in memory, without having the
UI portion present, but not vice versa.  The UI can come and go, (load
and unload) while the code module persists (stays in memory).  Thats
why variables you declare at the module level (of a Form for example)
keep their values, even after the form is unloaded.  The variables are part
of the code module.  The values persist as long as the code module
stays in memory.

The New command loads a module into memory, and setting that (and
all other) reference to Nothing removes it from memory (theoretically).
The Load command loads the UI portion into memory and the Unload
command removes it.

I don't see the confusion, they are two different things, and they have
their own commands and their own events....

???
LFS
Author
5 Jun 2009 1:02 PM
MM
On Fri, 5 Jun 2009 07:04:33 -0500, "Larry Serflaten"
<serfla***@usinternet.com> wrote:

> Thats
>why variables you declare at the module level (of a Form for example)
>keep their values, even after the form is unloaded.

So the right place to Set m_Whatever = Nothing *is* in Form_Terminate?

MM
Author
5 Jun 2009 1:11 PM
MM
On Fri, 5 Jun 2009 07:04:33 -0500, "Larry Serflaten"
<serfla***@usinternet.com> wrote:

>I don't see the confusion....

You may not see any, but all I see is mud, i.e. clear as mud, and lots
of it. For instance, I can put App.HelpFile = "c:\windows\dssock.hlp"
in Form_Load, Form_Initialize or Form_Activate. It works in every
location. But what does Microsoft say is the *right* location?

Say my app has a user control cTile.cls. I can place

Set m_Tile = New cTile

in Form_Initialize, Form_Load or Form_Activate and VB doesn't barf.

So, again, what is the recommended way? Which VB6 book is the best at
explaining all these issues? (I'm not interested in noddy books that
show me how to place a command button on a form...!)

MM
Author
5 Jun 2009 2:11 PM
Larry Serflaten
"MM" <kylix***@yahoo.co.uk> wrote
> >I don't see the confusion....
>
> You may not see any, but all I see is mud, i.e. clear as mud,

Let me try this:

I could double a value using multiplication:

  X = X * 2

Or, I could double a value using addition:

X = X + X

But which is the 'right' way?

Do you see what you're asking?  More than one solution should not add confusion.

Typically, as a general rule, if you have things that belong with the code module,
put them with the code module.  If they belong with the UI, then put them with the UI.

If that doesn't work out as intended, (known bug, whatever) then make an exception
and do what you need to do to get it working correctly.

LFS
Author
5 Jun 2009 2:30 PM
Larry Serflaten
> Which VB6 book is the best at
> explaining all these issues? (I'm not interested in noddy books that
> show me how to place a command button on a form...!)

Two books you might want in your library include Hardcore VB
http://vb.mvps.org/hcvb.asp

And Advanced Visual Basic 6
http://www.powervb.com/

Hardcore VB (although dated) is available online (free) and helps you
understand how things work, while Adv VB (~ $35 USD) teaches techniques
that let you do things that were seemingly impossible with VB.  It does that
by adding the understanding behind the concepts.

Have a look, see what you think...
LFS
Author
5 Jun 2009 3:35 PM
Ralph
"Larry Serflaten" <serfla***@usinternet.com> wrote in message
news:utmg4ne5JHA.1528@TK2MSFTNGP05.phx.gbl...
>
> And Advanced Visual Basic 6
> http://www.powervb.com/
>

I most heartily agree. It should be considered required reading for all VB
programmers. Even if they never use any of the "advanced" techniques.

-ralph
Author
6 Jun 2009 5:34 AM
MM
On Fri, 5 Jun 2009 09:30:42 -0500, "Larry Serflaten"
<serfla***@usinternet.com> wrote:

Show quoteHide quote
>> Which VB6 book is the best at
>> explaining all these issues? (I'm not interested in noddy books that
>> show me how to place a command button on a form...!)
>
>Two books you might want in your library include Hardcore VB
>http://vb.mvps.org/hcvb.asp
>
>And Advanced Visual Basic 6
>http://www.powervb.com/
>
>Hardcore VB (although dated) is available online (free) and helps you
>understand how things work, while Adv VB (~ $35 USD) teaches techniques
>that let you do things that were seemingly impossible with VB.  It does that
>by adding the understanding behind the concepts.
>
>Have a look, see what you think...
>LFS

Thanks. I note that Advanced Visual Basic 6 is available secondhand
from Amazon.co.uk Marketplace at a low price (around 7 pounds sterling
including delivery), so I may well get it. I already have Bruce
McKinney's Hardcore VB in its first (1995) edition.

MM
Author
6 Jun 2009 7:45 AM
Ralph
Show quote Hide quote
"MM" <kylix***@yahoo.co.uk> wrote in message
news:nivj25p69bcprs3smaunck1bk8a45rra6i@4ax.com...
> On Fri, 5 Jun 2009 09:30:42 -0500, "Larry Serflaten"
> <serfla***@usinternet.com> wrote:
>
> >> Which VB6 book is the best at
> >> explaining all these issues? (I'm not interested in noddy books that
> >> show me how to place a command button on a form...!)
> >
> >Two books you might want in your library include Hardcore VB
> >http://vb.mvps.org/hcvb.asp
> >
> >And Advanced Visual Basic 6
> >http://www.powervb.com/
> >
> >Hardcore VB (although dated) is available online (free) and helps you
> >understand how things work, while Adv VB (~ $35 USD) teaches techniques
> >that let you do things that were seemingly impossible with VB.  It does
that
> >by adding the understanding behind the concepts.
> >
> >Have a look, see what you think...
> >LFS
>
> Thanks. I note that Advanced Visual Basic 6 is available secondhand
> from Amazon.co.uk Marketplace at a low price (around 7 pounds sterling
> including delivery), so I may well get it. I already have Bruce
> McKinney's Hardcore VB in its first (1995) edition.
>

If you have the first edition of McKinney's Hardcord VB, you may want to
consider getting his 2nd Edition. But if without the 2nd edition you should
find this interesting:

"Saying Goodbye to Hardcore Visual Basic"
by Bruce McKinney
http://brucem.mystarband.net/mckinney.htm

The Appendics alone are a woot.

-ralph
Author
6 Jun 2009 9:08 AM
MM
On Sat, 6 Jun 2009 02:45:39 -0500, "Ralph" <nt_consultin***@yahoo.com>
wrote:

>"Saying Goodbye to Hardcore Visual Basic"

I can recall having read that not long after he wrote it, but, yes, I
am sure it is worth reading again. This (sigh) holds for so many
books, though, but there is just not enough time! Code Complete is one
such.

MM
Author
6 Jun 2009 1:51 PM
mayayana
--
>
> >> Which VB6 book is the best at
> >> explaining all these issues? (I'm not interested in noddy books that
> >> show me how to place a command button on a form...!)
> >

  Another one is Dan Appleman's ActiveX book. (NOT
his API book.)
   I share your feeling about VB books and programming
books in general....or books for that matter. It's amazing
how much -- or how little -- can go into two similar books.
I wasted a lot of money on VB books at first, before I
realized that nearly all of them were starter books
masquerading as full-scale references. Oddly, it seems
that the ones recommended by MS are often the worst.
(Like the Que books that are always really big, really
expensive, with big type and lots of white space. :)

  One note worth mentioning about Advanced
Visual Basic 6: Although I'd cast my vote with everyone
else -- Matthew Curland's curious mind and his obvious
love of the topic make his book a pleasure to read, and
some of his advice is nowhere else to be found --
nevertheless his book is rather dated and he hasn't
released any update. I used his subclassing method
for a long time. It worked great. But it used a snippet
of linine assembly that conflicts with DEP in Vista+,
in XP SP3 shell extensions, and in XP itself if people
select restrictive DEP settings. Curland's code will now
cause your program to crash when opened. I noticed
that you seem to be using the VBAccel. method of
subclassing, which is apparently fine. Another method,
which I found out about here recently, is the code by
Paul Caton and others.
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=68737&ln
gWId=1

  I reduced that code to a class of 30+ KB for
my own subclassing. It's
almost as easy as Matthew Curland's method.
I can subclass dozens of UserControls that are
all self-subclassing and require no special attention
once I've set up the WindowProc in the UC. It can
all be done with just one instance of the subclassing
class, it allows breaks in the IDE (somewhat), and
it's DEP-safe.
Author
5 Jun 2009 4:30 PM
Ralph
Show quote Hide quote
"MM" <kylix***@yahoo.co.uk> wrote in message
news:5v5i25dctc91ndutpkfmqqtq3q29kkb5a5@4ax.com...
> On Fri, 5 Jun 2009 07:04:33 -0500, "Larry Serflaten"
> <serfla***@usinternet.com> wrote:
>
> >I don't see the confusion....
>
> You may not see any, but all I see is mud, i.e. clear as mud, and lots
> of it. For instance, I can put App.HelpFile = "c:\windows\dssock.hlp"
> in Form_Load, Form_Initialize or Form_Activate. It works in every
> location. But what does Microsoft say is the *right* location?
>
> Say my app has a user control cTile.cls. I can place
>
> Set m_Tile = New cTile
>
> in Form_Initialize, Form_Load or Form_Activate and VB doesn't barf.
>
> So, again, what is the recommended way? Which VB6 book is the best at
> explaining all these issues? (I'm not interested in noddy books that
> show me how to place a command button on a form...!)
>

Here's a quick cheatsheet:
[More or less Air Code! But I trust it will be quickly amended. lol]
General order of events:
    _Initialize       ' pairs with Terminate
    _Load           ' pairs with _Unload
    (_Resize)
    _Activate        ' perhaps multiple time paired
    (_Paint)
    _Deactivate     ' perhaps multiple times
    _QueryUnload
    _Unload           ' pairs with _Load
    _Terminate       ' pairs with Initialize

_Initialize
   * The form has been New'd (or been referenced with the intrinistic
reference)
   * The form
   * The form object has been created, the WindowClass is registered and a
WinProc is set up. (But the actual 'Window' or Karl's 'UI' hasn't been built
or assembled yet.)
   * You can assign/create some of the form's member data, but you can't
touch anything in the 'UI'
    * No communication to the outside world yet.
    * Initialize only happens once for a Form object, ie, you can have
multiple reference to the same form, but _Initialize only once.

_Load
   * The Form object now builds it's 'UI'.
    * Creates the Window and it's child controls
    * Each of which get their own Initialize/Load
        (That's where the default properties get set.)
    * You then get a chance to add your two cents to the process.
    * Happens before the form is shown
       (Activate tells you the form is visible and ready for user input)
    * A form is loaded if you call Show, or if a property, method, (or in
some cases) a child control of the Form.
       (If doing the latter - it is loaded but not shown)
    * Do not call Unload from inside _Load. The form is in a odd state of
being, so if you do all hell can break lose. lol
    * You can fire events, open files, ie, - talk to the outside world

_Activate
    * Triggered anytime the form gets focus
    * Show will fire it
    * Essentially says form is now available for user input
    * Occurs when focus is shifted to another form and then back again.
     * But only within the program. Not if changing focus between it and
another program.
    * Also in the IDE changing focus doesn't always fire _Activate (or
_Deactivate). Therefore always test code in these events with a compiled
program.
     * This is the main reasons programmers report problems with this event.
They test in one environment and then get suprised later.

_Deactivate
     * Triggered anytime the form loses focus
      * Note the Gotcha's with _Activate
      * Hide will fire _Deactivate

_Unload
      * Fires when a form is going bye-bye
      * last chance to communicate with the 'UI' child controls, etc.
      * Unload fires this

_Terminate
       * one last chance to communicate with the form's data
       * but you can't talk to the outside, no events, no resources

Whew!
-ralph
Author
5 Jun 2009 4:37 PM
Bob Butler
"Ralph" <nt_consultin***@yahoo.com> wrote in message
news:OOJNksf5JHA.1528@TK2MSFTNGP05.phx.gbl...
<cut>
>    * Do not call Unload from inside _Load. The form is in a odd state of
> being, so if you do all hell can break lose. lol

I've never had a problem with that;  if the load was called from other code
then it may need error trapping but hell has yet to break loose. <g>
Author
5 Jun 2009 4:54 PM
Ralph
"Bob Butler" <noway@nospam.ever> wrote in message
news:OP%23dOwf5JHA.4780@TK2MSFTNGP06.phx.gbl...
>
> "Ralph" <nt_consultin***@yahoo.com> wrote in message
> news:OOJNksf5JHA.1528@TK2MSFTNGP05.phx.gbl...
> <cut>
> >    * Do not call Unload from inside _Load. The form is in a odd state of
> > being, so if you do all hell can break lose. lol
>
> I've never had a problem with that;  if the load was called from other
code
> then it may need error trapping but hell has yet to break loose. <g>
>

True. I over-hyphed it. (Is that a word?)
I have gotten bitten (probably more a control problem), so I just don't go
there.
Should have said "IMHO".

-ralph
Author
5 Jun 2009 6:54 PM
MM
Show quote Hide quote
On Fri, 5 Jun 2009 11:30:15 -0500, "Ralph" <nt_consultin***@yahoo.com>
wrote:

>
>"MM" <kylix***@yahoo.co.uk> wrote in message
>news:5v5i25dctc91ndutpkfmqqtq3q29kkb5a5@4ax.com...
>> On Fri, 5 Jun 2009 07:04:33 -0500, "Larry Serflaten"
>> <serfla***@usinternet.com> wrote:
>>
>> >I don't see the confusion....
>>
>> You may not see any, but all I see is mud, i.e. clear as mud, and lots
>> of it. For instance, I can put App.HelpFile = "c:\windows\dssock.hlp"
>> in Form_Load, Form_Initialize or Form_Activate. It works in every
>> location. But what does Microsoft say is the *right* location?
>>
>> Say my app has a user control cTile.cls. I can place
>>
>> Set m_Tile = New cTile
>>
>> in Form_Initialize, Form_Load or Form_Activate and VB doesn't barf.
>>
>> So, again, what is the recommended way? Which VB6 book is the best at
>> explaining all these issues? (I'm not interested in noddy books that
>> show me how to place a command button on a form...!)
>>
>
>Here's a quick cheatsheet:
>[More or less Air Code! But I trust it will be quickly amended. lol]
>General order of events:
>    _Initialize       ' pairs with Terminate
>    _Load           ' pairs with _Unload
>    (_Resize)
>    _Activate        ' perhaps multiple time paired
>    (_Paint)
>    _Deactivate     ' perhaps multiple times
>    _QueryUnload
>    _Unload           ' pairs with _Load
>    _Terminate       ' pairs with Initialize
>
>_Initialize
>   * The form has been New'd (or been referenced with the intrinistic
>reference)
>   * The form
>   * The form object has been created, the WindowClass is registered and a
>WinProc is set up. (But the actual 'Window' or Karl's 'UI' hasn't been built
>or assembled yet.)
>   * You can assign/create some of the form's member data, but you can't
>touch anything in the 'UI'
>    * No communication to the outside world yet.
>    * Initialize only happens once for a Form object, ie, you can have
>multiple reference to the same form, but _Initialize only once.
>
>_Load
>   * The Form object now builds it's 'UI'.
>    * Creates the Window and it's child controls
>    * Each of which get their own Initialize/Load
>        (That's where the default properties get set.)
>    * You then get a chance to add your two cents to the process.
>    * Happens before the form is shown
>       (Activate tells you the form is visible and ready for user input)
>    * A form is loaded if you call Show, or if a property, method, (or in
>some cases) a child control of the Form.
>       (If doing the latter - it is loaded but not shown)
>    * Do not call Unload from inside _Load. The form is in a odd state of
>being, so if you do all hell can break lose. lol
>    * You can fire events, open files, ie, - talk to the outside world
>
>_Activate
>    * Triggered anytime the form gets focus
>    * Show will fire it
>    * Essentially says form is now available for user input
>    * Occurs when focus is shifted to another form and then back again.
>     * But only within the program. Not if changing focus between it and
>another program.
>    * Also in the IDE changing focus doesn't always fire _Activate (or
>_Deactivate). Therefore always test code in these events with a compiled
>program.
>     * This is the main reasons programmers report problems with this event.
>They test in one environment and then get suprised later.
>
>_Deactivate
>     * Triggered anytime the form loses focus
>      * Note the Gotcha's with _Activate
>      * Hide will fire _Deactivate
>
>_Unload
>      * Fires when a form is going bye-bye
>      * last chance to communicate with the 'UI' child controls, etc.
>      * Unload fires this
>
>_Terminate
>       * one last chance to communicate with the form's data
>       * but you can't talk to the outside, no events, no resources
>
>Whew!
>-ralph
>

Now THAT was facinating! Thanks.

MM
Author
5 Jun 2009 3:32 PM
Ralph
Show quote Hide quote
"Larry Serflaten" <serfla***@usinternet.com> wrote in message
news:ehOMNWd5JHA.1424@TK2MSFTNGP02.phx.gbl...
>
> "MM" <kylix***@yahoo.co.uk> wrote
>
> > That said, I am going to pay far greater attention to how objects are
> > created and destroyed. I still don't understand the significance of
> > the Form_Terminate event properly, though. Wish there was a lengthy
> > description of all these more obscure events! Initialize is another
> > one. And Form_Activate yet another!
>
> I don't see where the problem is.  VB loads modules on demand, so if
> you never call up an object, it doesn't get loaded into memory.  When
> you do call one up, it first has to initialize the memory (variables set
to 0
> and all that) and they give you a chance to act on that event too.  When
> it is no longer needed, it is removed from memory, appropreatly called
> terminated, and you can act on that event also.
>
> If the object you call up has a User Interface (like Forms do) that is a
> seperate entity from the plain jane code module that classes have.  When
> that is brought into memory it goes through another initialization phase
> (UI properties, control locations, etc) and you get an event to use when
> that happens.  Likewise when the UI is tearing down, (unloading) you
> get an event there as well.
>
> You can have the code module present in memory, without having the
> UI portion present, but not vice versa.  The UI can come and go, (load
> and unload) while the code module persists (stays in memory).  Thats
> why variables you declare at the module level (of a Form for example)
> keep their values, even after the form is unloaded.  The variables are
part
> of the code module.  The values persist as long as the code module
> stays in memory.
>
> The New command loads a module into memory, and setting that (and
> all other) reference to Nothing removes it from memory (theoretically).
> The Load command loads the UI portion into memory and the Unload
> command removes it.
>
> I don't see the confusion, they are two different things, and they have
> their own commands and their own events....
>

Your observations are correct, but there is one minor point that perhaps
needs amplification, and that is the use of the expression "loads a module
into memory". To see what I mean take a look at MS's use of it in this
article.

"Differences Among Form's Initialize, Load, and Activate Events"
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q138819

And it isn't just there. MS has stated that "Forms get loaded into memory"
when the load event is called in all documentation since VB 1 (and the
quickly to follow VB 1.1.). It was even more odd then as earlier VBs
actually loaded all forms into memory when the program was launched.

And it doesn't take much reasoning power to notice that if a Form object
doesn't exist until the Load event is called - who the heck did the sender
send/post the Initialize Event to? :-)

The only reason I bring it up is because if you tell enough students,
programmers, or write that enough times - ever so often someone will raise
their hand and challenge you with articles and books in hand. That is if you
are lucky. More often those that spot it only wander off with the knowledge
you lied to them. lol

I have taken to just saying a VB Form is instanced and initialized (aka,
"loaded into memory" lol) upon calling New or using the intrinsic Form name
reference and just go with MS's documentation even though it is "technically
incorrect". As both you and Karl have pointed out. (Though some dependent
objects do only become loaded into memory when the Load Event is called. So
there is always some wiggle room. <smile>)

You also make a good point in noting that one can easily overly-think the
situation.

-ralph
Author
5 Jun 2009 6:08 PM
Larry Serflaten
"Ralph" <nt_consultin***@yahoo.com> wrote

> Your observations are correct, but there is one minor point that perhaps
> needs amplification, and that is the use of the expression "loads a module
> into memory". To see what I mean take a look at MS's use of it in this
> article.
>
> "Differences Among Form's Initialize, Load, and Activate Events"
> http://support.microsoft.com/default.aspx?scid=kb;en-us;Q138819
>
> And it isn't just there. MS has stated that "Forms get loaded into memory"
> when the load event is called in all documentation since VB 1 (and the
> quickly to follow VB 1.1.).

Perhaps technically correct, there is precedent for saying the two (module and
UI) are 'loaded into memory' separately.  For example, a form can be initialized
and Subs called prior to the Load event.  So, you've got to ask, where are those
subroutines residing that they can be called prior to it being loaded?  They must
be present in memory to be executed, therefore instantiating the form brings its
'code module' into memory.  For documentation, I'd refer you to this:

Life Cycle of Visual Basic Forms
http://msdn.microsoft.com/en-us/library/aa242139(VS.60).aspx

"The beginning of this state is marked by the Initialize event.
Code you place in the Form_Initialize event procedure is
therefore the first code that gets executed when a form is created.

In this state, the form exists as an object, but it has no window.
None of its controls exist yet. A form always passes through this
state, although its stay there may be brief."

.... and ...

"Once Form_Initialize has ended, the only procedures you
can execute without forcing the form to load are Sub,
Function, and Property procedures you've added to the
form's code window."


Note the 'form exists as an object'.  That is a very similar state
to what a class (object) produces.  I was hoping to draw enough
corelation between the two to make it seem like the form is actually
two separate entities, a class module part and a UI part.  That would
help to illustrate the two are basically similar, with a form having
a secondary UI part.

I was hoping to get MM to apply an understanding of the class
life cycle, to the different parts and life cycle of the form.  I think
its a fair analogy....

LFS
Author
5 Jun 2009 7:16 PM
MM
On Fri, 5 Jun 2009 13:08:24 -0500, "Larry Serflaten"
<serfla***@usinternet.com> wrote:

Show quoteHide quote
>
>"Ralph" <nt_consultin***@yahoo.com> wrote
>
>> Your observations are correct, but there is one minor point that perhaps
>> needs amplification, and that is the use of the expression "loads a module
>> into memory". To see what I mean take a look at MS's use of it in this
>> article.
>>
>> "Differences Among Form's Initialize, Load, and Activate Events"
>> http://support.microsoft.com/default.aspx?scid=kb;en-us;Q138819
>>
>> And it isn't just there. MS has stated that "Forms get loaded into memory"
>> when the load event is called in all documentation since VB 1 (and the
>> quickly to follow VB 1.1.).
>
>Perhaps technically correct, there is precedent for saying the two (module and
>UI) are 'loaded into memory' separately.  For example, a form can be initialized
>and Subs called prior to the Load event.  So, you've got to ask, where are those
>subroutines residing that they can be called prior to it being loaded?  They must
>be present in memory to be executed, therefore instantiating the form brings its
>'code module' into memory.  For documentation, I'd refer you to this:
>
>Life Cycle of Visual Basic Forms
>http://msdn.microsoft.com/en-us/library/aa242139(VS.60).aspx
>
>"The beginning of this state is marked by the Initialize event.
>Code you place in the Form_Initialize event procedure is
>therefore the first code that gets executed when a form is created.

I've just read that in the link you gave above, but, typical
Microsoft, NO examples are given! One might expect that MS could have
suggested what kind of code might be typically suited for
Form_Initialize.

Question: What kind of code absolutely HAS to appear in
Form_Initialize and nowhere else?

Similarly, what kind of code absolutely HAS to appear in
Form_Terminate and nowhere else?

Show quoteHide quote
>In this state, the form exists as an object, but it has no window.
>None of its controls exist yet. A form always passes through this
>state, although its stay there may be brief."
>
>... and ...
>
>"Once Form_Initialize has ended, the only procedures you
>can execute without forcing the form to load are Sub,
>Function, and Property procedures you've added to the
>form's code window."
>
>
>Note the 'form exists as an object'.  That is a very similar state
>to what a class (object) produces.  I was hoping to draw enough
>corelation between the two to make it seem like the form is actually
>two separate entities, a class module part and a UI part.  That would
>help to illustrate the two are basically similar, with a form having
>a secondary UI part.
>
>I was hoping to get MM to apply an understanding of the class
>life cycle, to the different parts and life cycle of the form.  I think
>its a fair analogy....

Well, I'm doing my best! Hang in there!

MM
Author
5 Jun 2009 10:18 PM
Ralph
"MM" <kylix***@yahoo.co.uk> wrote in message
news:06ri251844s82d5amqmhjl26kqskvgtt4b@4ax.com...
>
> Question: What kind of code absolutely HAS to appear in
> Form_Initialize and nowhere else?
>
> Similarly, what kind of code absolutely HAS to appear in
> Form_Terminate and nowhere else?
>

For a Form No code absolutely HAS to appear in _Initialize or _Terminate and
nowhere else. Except perhaps some debug routine to report a class has
initialized. or terminated.

Of course one should never say never, it might be possible to come up with
something that works better there with some kind of forced flow control, but
it is just as likely you could turn around and port that code into
_Load/_Unload and get the same results.

You will even find some 'experts' suggest that you never use them. Their
reason - if they fail, they do so with little reporting back to the program.
Not that you can't - just you are limited.

For Classes (and for Forms), put anything there to set up the Class data
(members) that has to be there before the Client touches the class, that has
a limited ability to fail. But even there - you are limited. You cannot
receive outside arguments and you can't fail graciously. Best to provide
your own _Init/_Open or _Destroy/_Close methods. They can take arguments,
return arguments, and report errors back.

-ralph
Author
5 Jun 2009 8:08 PM
Ralph
Show quote Hide quote
"Larry Serflaten" <serfla***@usinternet.com> wrote in message
news:Os9Fihg5JHA.1420@TK2MSFTNGP04.phx.gbl...
>
> "Ralph" <nt_consultin***@yahoo.com> wrote
>
> > Your observations are correct, but there is one minor point that perhaps
> > needs amplification, and that is the use of the expression "loads a
module
> > into memory". To see what I mean take a look at MS's use of it in this
> > article.
> >
> > "Differences Among Form's Initialize, Load, and Activate Events"
> > http://support.microsoft.com/default.aspx?scid=kb;en-us;Q138819
> >
> > And it isn't just there. MS has stated that "Forms get loaded into
memory"
> > when the load event is called in all documentation since VB 1 (and the
> > quickly to follow VB 1.1.).
>
> Perhaps technically correct, there is precedent for saying the two (module
and
> UI) are 'loaded into memory' separately.  For example, a form can be
initialized
> and Subs called prior to the Load event.  So, you've got to ask, where are
those
> subroutines residing that they can be called prior to it being loaded?
They must
> be present in memory to be executed, therefore instantiating the form
brings its
> 'code module' into memory.  For documentation, I'd refer you to this:
>
> Life Cycle of Visual Basic Forms
> http://msdn.microsoft.com/en-us/library/aa242139(VS.60).aspx
>
> "The beginning of this state is marked by the Initialize event.
> Code you place in the Form_Initialize event procedure is
> therefore the first code that gets executed when a form is created.
>
> In this state, the form exists as an object, but it has no window.
> None of its controls exist yet. A form always passes through this
> state, although its stay there may be brief."
>
> ... and ...
>
> "Once Form_Initialize has ended, the only procedures you
> can execute without forcing the form to load are Sub,
> Function, and Property procedures you've added to the
> form's code window."
>
>
> Note the 'form exists as an object'.  That is a very similar state
> to what a class (object) produces.  I was hoping to draw enough
> corelation between the two to make it seem like the form is actually
> two separate entities, a class module part and a UI part.  That would
> help to illustrate the two are basically similar, with a form having
> a secondary UI part.
>
> I was hoping to get MM to apply an understanding of the class
> life cycle, to the different parts and life cycle of the form.  I think
> its a fair analogy....
>

That is the "wiggle room" I was speaking of.

And your analogy of "two" objects is correct as there are in fact two
separate objects ( or three or four - depending on how deep you want to go).

VB is based on COM. Note: the *protocol*, not necessarily all of the OLE
implementation. The VB runtime implements many parts of the COM protocol
with its own custom implementation.

COM supports Interface Inheritance by aggregation. A 'finished' instanced VB
Form (eg, Form1) is in fact the object created by the Form1 class with the
VBForm object's Public* Interface tacked on, which is essentially
"pass-through".

-ralph
Author
5 Jun 2009 6:22 PM
Larry Serflaten
"Ralph" <nt_consultin***@yahoo.com> wrote

> Your observations are correct, but there is one minor point that perhaps
> needs amplification, and that is the use of the expression "loads a module
> into memory".

One last AHA!

On the life cycle page referenced in my earlier post, near the bottom (about
an odd fifth state) there is this statement:

"The form has been unloaded, and all references to it released.
However, you still have a reference to one of its controls,
and this will keep the code part of the form from releasing
the memory it's using."

"the code part of the form"  Hmmm.....  Exactly when was that
loaded into memory?  Admittedly I have to guess, but I bet a steak
dinner that part was brought into memory when the form was
created (before the form was loaded).

<g>
LFS
Author
5 Jun 2009 6:31 PM
Nobody
Show quote Hide quote
"Larry Serflaten" <serfla***@usinternet.com> wrote in message
news:uMJPUpg5JHA.6004@TK2MSFTNGP02.phx.gbl...
>
> "Ralph" <nt_consultin***@yahoo.com> wrote
>
>> Your observations are correct, but there is one minor point that perhaps
>> needs amplification, and that is the use of the expression "loads a
>> module
>> into memory".
>
> One last AHA!
>
> On the life cycle page referenced in my earlier post, near the bottom
> (about
> an odd fifth state) there is this statement:
>
> "The form has been unloaded, and all references to it released.
> However, you still have a reference to one of its controls,
> and this will keep the code part of the form from releasing
> the memory it's using."
>
> "the code part of the form"  Hmmm.....  Exactly when was that
> loaded into memory?  Admittedly I have to guess, but I bet a steak
> dinner that part was brought into memory when the form was
> created (before the form was loaded).
>
> <g>
> LFS

See this thread:

HOW IS Memory Used by a VB App
http://groups.google.com/group/microsoft.public.vb.general.discussion/browse_thread/thread/bb3aba85e3d9eb09/9a06efa5b28ae0f4

In particular, this post:

http://groups.google.com/group/microsoft.public.vb.general.discussion/msg/ae8f4cc6333bf85e
Author
5 Jun 2009 7:09 PM
Larry Serflaten
"Nobody" <nob***@nobody.com> wrote

> In particular, this post:
>
> http://groups.google.com/group/microsoft.public.vb.general.discussion/msg/ae8f4cc6333bf85e


Good point.  In this instance, however, adding VM into the mix (or how files are handled by Windows) would only cloud the
picture.

Whether you have a stub (for lack of a better word) or the actual routines isn't really the issue.  That one (or the other) is
hanging around in memory is the concern.  Still, worthy of note for those who are interested.....

LFS
Author
5 Jun 2009 5:28 PM
Nobody
In MSDN library, search by title the following topics:

Life Cycle of Visual Basic Forms
Object References and Reference Counting
Understanding Control Lifetime and Key Events

One problem that you may not be aware of is that the variables declared in
the general section of a form are not re-initialized to zero when the user
closes a form, and you try to show it again using the form's hidden global
variable, such as Form1. That's because VB declares it for you like the
following:

Public Form1 As New Form1

In that case, the form is auto created on first use, and the reference is
still valid after closing the form, and Form_Terminate is not called,
because the reference count is not zero.

Try this example(Karl gave you air code, which does not work as he
intended):

- Start a new project, and add a CommandButton to Form1, and add a new Form2
without controls, and use the following code:

' Form1 code =================

Option Explicit

Private Sub Command1_Click()
    Form2.Show
End Sub

' Form2 code =================

Option Explicit

Dim Counter As Long

Private Sub Form_Activate()
    Debug.Print "Form_Activate: " & Timer
End Sub

Private Sub Form_Initialize()
    Debug.Print "Form_Initialize: " & Timer
End Sub

Private Sub Form_Load()
    Counter = Counter + 1
    Debug.Print "Form_Load: Counter = " & Counter & ", " & Timer
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Debug.Print "Form_Unload: " & Timer
End Sub

Private Sub Form_Terminate()
    Debug.Print "Form_Terminate: " & Timer
End Sub

' ========================


Now, start the project and click on the button, this shows Form2. Counter
would become 1. Now close Form2, and click Command1 button to show Form2
again. Instead of Counter being set to 0 again, it kept its old value, and
Debug.Print prints 2. Here is an example output:

Form_Initialize: 47248.97
Form_Load: Counter = 1, 47248.97
Form_Activate: 47248.98
Form_Unload: 47258.52
Form_Load: Counter = 2, 47261.06
Form_Activate: 47261.08
Form_Unload: 47267.94
Form_Terminate: 47270.72

"Form_Terminate" was called when I closed both forms.

The same thing happens if you use "Unload Form2" in code. One solution is to
use the following line as the last line in Form_Unload:

Set Form2 = Nothing

I am not sure if this is considered a clean solution. Most would use the
following in Command1_Click, which is a cleaner solution:

Private Sub Command1_Click()
    Dim frm As Form2

    Set frm = New Form2
    frm.Show
    Set frm = Nothing
End Sub


This method allows you to create multiple windows, for example, to display
different text files for editing. While "frm" is being set to Nothing, and
this should unload the form, VB adds an additional reference to the form
when its loaded(for use internally), making the reference count greater and
the form stays loaded.