|
-
May 15th, 2013, 03:02 AM
#1
Thread Starter
Hyperactive Member
[RESOLVED] Unload Me
Hi VB friends,
I am a bit confused whenever I use the Unload event...That is because each time we have to unload the form and to release the reference to the form.
My issue is I don't understand very well which is the correct sequence of this process : should I set to nothing the form as a first line of code or simply to unload the form and after that to set it as nothing ? For example I have a second form which I want to unload it properly :
Code:
Private Sub Form_Unload(Cancel As Integer)
Unload Me
Set Form2 = Nothing
End Sub
Is this sequence correct or it doesn't matter any order ? On the other hand, the Me argument couldn't be replaced with Form2 (... Unload Form2) ?
Thank you in advance.
-
May 15th, 2013, 03:07 AM
#2
Banned
Re: Unload Me
unload me is for closing 1 form but there is a code using for each method that will close all forms same time
use this
it will kill all forms instantly
Code:
Private Sub Command2_Click()
Dim f As Integer
f = Forms.Count
Do While f > 0
Unload Forms(f - 1)
If f = Forms.Count Then Exit Do
f = f - 1
Loop
End Sub
or
Code:
Private Sub Form_Unload(Cancel As Integer)
Dim f As Integer
f = Forms.Count
Do While f > 0
Unload Forms(f - 1)
If f = Forms.Count Then Exit Do
f = f - 1
End Sub
bump
form2 nothing code is unsless it doesnt unload dont use that
Last edited by ladoo; May 15th, 2013 at 03:11 AM.
-
May 15th, 2013, 03:44 AM
#3
Thread Starter
Hyperactive Member
Re: Unload Me
Hi Ladoo,
Thanks for suggestions. Actually I am looking for a theoretical explanation. I have no doubt that your code can unload N-1 forms involved in an application but is really useless this releasing : Set Form2 = Nothing !? In terms of good practice many programmers recommend it ...Regarding your solutions above I don't understand why do you loop using "Do While" as long as you already know the Form.Count limit ? Rewriting these lines I would prefer something like below :
Code:
Private Sub Form_Unload(Cancel As Integer)
Dim i As Byte
For i = 1 To Forms.Count - 1
Unload Forms(i)
Next i
End Sub
Isn't it the same thing ? Thank you.
-
May 15th, 2013, 05:56 AM
#4
Re: Unload Me
If you are unloading all forms in the application (shutting down the app) then you can use a for loop. In that case I would skip setting the form to nothing.
Code:
Dim frm As Form
For Each frm In Forms
Unload frm
Next frm
 Originally Posted by ladoo
form2 nothing code is unsless it doesnt unload dont use that
If you are closing an individual form there is cause to setting the form to nothing. Give this a try. Create a project with 2 forms. Run the app and click the button to show form2. Enter somthing in the textbox and then click the unload button then on form1 show form2 again. Anything unexpected happen? Now click the unload and destroy button and then show form2 again.
Form1 has a single command button.
Code:
Private Sub Command1_Click()
Form2.Show
End Sub
Form2 has 1 textbox and 2 command buttons
Code:
Option Explicit
Dim strStartUpText As String
Private Sub Command1_Click()
Unload Me
End Sub
Private Sub Command2_Click()
Unload Form2
Set Form2 = Nothing
End Sub
Private Sub Form_Load()
Text1.Text = strStartUpText
Command1.Caption = "Unload"
Command2.Caption = "Unload and Destroy"
End Sub
Private Sub Form_Unload(Cancel As Integer)
strStartUpText = Text1.Text
End Sub
Last edited by MarkT; May 15th, 2013 at 06:01 AM.
-
May 15th, 2013, 09:19 AM
#5
Re: Unload Me
 Originally Posted by Daniel Duta
Actually I am looking for a theoretical explanation.
Excerpted from the Life Cycle of Visual Basic Forms:
Returning to the Created, But Not Loaded State
When the form is unloaded, Visual Basic removes it from the Forms collection. Unless you've kept a variable around with a reference to the form in it, the form will be destroyed, and its memory and resources will be reclaimed by Visual Basic.
If you kept a reference to the form in a variable somewhere, such as the hidden global variable described in "Customizing Form Classes," then the form returns to the Created, But Not Loaded state. The form no longer has a window, and its controls no longer exist.
The object is still holding on to resources and memory. All of the data in the module-level variables in the form's code part are still there. (Static variables in event procedures, however, are gone.)
You can use that reference you've been keeping to call the methods and properties that you added to the form, but if you invoke the form's built-in members, or access its controls, the form will load again, and Form_Load will execute.
Memory and Resources Completely Reclaimed
The only way to release all memory and resources is to unload the form and then set all references to Nothing. The reference most commonly overlooked when doing this is the hidden global variable mentioned earlier. If at any time you have referred to the form by its class name (as shown in the Properties Window by the Name property), you've used the hidden global variable. To free the form's memory, you must set this variable to Nothing. For example:
Set Form1 = Nothing
Your form will receive its Terminate event just before it is destroyed.
Tip Many professional programmers avoid the use of the hidden global variable, preferring to declare their own form variables (for example, Dim dlgAbout As New frmAboutBox) to manage form lifetime.
Note Executing the End statement unloads all forms and sets all object variables in your program to Nothing. However, this is a very abrupt way to terminate your program. None of your forms will get their QueryUnload, Unload, or Terminate events, and objects you've created will not get their Terminate events.
Extracted from Customizing Form Classes:
Me and My Hidden Global Variable
You may be wondering how it is that you can refer to Form1 in code, as if it were an object variable. There's no magic involved. Visual Basic creates a hidden global object variable for every form class. It's as if Visual Basic had added the following declaration to your project:
Public Form1 As New Form1
When you select Form1 as your startup object, or type Form1.Show in code, you're referring to this hidden global object variable. Because it's declared As New, an instance of the Form1 class is created the first time you use this predeclared variable in code.
The reason this declaration is hidden is that Visual Basic changes it every time you change the Name property of a form. In this way, the hidden variable always has the same name as the form class.
Tip After you unload a form, you should always set any references to the form to Nothing in order to free the memory and resources the form was using. The reference most often overlooked is the hidden global form variable.
Quoted from Basic Forms of Madness:
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
Dim oNewForm As New Form1 |
' Form1 is an object name
' 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).
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
May 15th, 2013, 03:13 PM
#6
Re: Unload Me
 Originally Posted by Daniel Duta
Hi Ladoo,
Thanks for suggestions. Actually I am looking for a theoretical explanation. I have no doubt that your code can unload N-1 forms involved in an application but is really useless this releasing : Set Form2 = Nothing !? In terms of good practice many programmers recommend it ...Regarding your solutions above I don't understand why do you loop using "Do While" as long as you already know the Form.Count limit ? Rewriting these lines I would prefer something like below :
Code:
Private Sub Form_Unload(Cancel As Integer)
Dim i As Byte
For i = 1 To Forms.Count - 1
Unload Forms(i)
Next i
End Sub
Isn't it the same thing ? Thank you.
No it's not the same thing... as soon as you unload a form, your Forms.Count drops by one... eventually the loop will hit the end of the array and complain about the index exceeding the bounds of the array
 Originally Posted by MarkT
If you are unloading all forms in the application (shutting down the app) then you can use a for loop. In that case I would skip setting the form to nothing.
Code:
Dim frm As Form
For Each frm In Forms
Unload frm
Next frm
I don't think that will work either because you cannot edit a collection while enumerating through it...
for those reasons is why the do while loop was used initially.
-tg
-
May 15th, 2013, 03:26 PM
#7
Re: Unload Me
 Originally Posted by techgnome
 Originally Posted by MarkT
Code:
Dim frm As Form
For Each frm In Forms
Unload frm
Next frm
I don't think that will work either because you cannot edit a collection while enumerating through it...
for those reasons is why the do while loop was used initially.
-tg
Are you sure about that? It has always worked for me.
-
May 15th, 2013, 07:04 PM
#8
Banned
-
May 16th, 2013, 12:33 AM
#9
Thread Starter
Hyperactive Member
Re: Unload Me
Hello guys,
Thank you all for your interest in this topic. The Bonnie's documented explanations are what I have expected to find from this thread.
The inconvenient truth is what was pointed out in the latest part of his post
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.
From this reason, ladoo, sometimes is better to find an answer to the question "why" rather than "how". I would say that in some cases even we have a relative knowledge we prefer to keep going forward without a clear understanding. I wonder what kind of programming is to handle Forms without consider them as part of a specific class : Dim myForm As New Form1 ...At least now I understand the role of Set myForm = Nothing.
Maybe the main source of confussion is VB does create each time Forms in a hidden way Public Form1 As New Form1 , the global object variable (in our case Form1) being considered/declared implicitly (why?!).
As a remark, the title metioned above was very inspired Thank you Bonnie that you shared us all these useful details. More than a discussion, I would consider your quotes as a short lesson.
-
May 16th, 2013, 12:52 AM
#10
Re: Unload Me
If you have finished with the thread please mark it "Resolved".
 Originally Posted by ladoo
 bump why not just finish off thread rather then discussion  bump 
Please do not bump threads without posting something constructive.
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|