Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Closing MDI children

Status
Not open for further replies.

AndyGroom

Programmer
May 23, 2001
972
GB
I've a long-standing problem with an MDI application.

When the user closes the MDI parent I would expect all the open MDI children to get a Form_QueryUnload event so that any open documents can be saved. However, neither the Form_Unload or Form_QueryUnload events seem to fire for the children when the parent closes.

Do I have to trigger these events manually in the MDI parent Form_Unload event or am I doing something wrong?

- Andy
___________________________________________________________________
If you think nobody cares you're alive, try missing a couple of mortgage payments
 
You shouldn't have to trigger these events manually, they may fire in a slightly different way than non MDI children (example coming) but they should still fire.

The way they fire slightly differently is that if you have multiple child forms open then each of their QueryUnload events will fire first (and as this is triggered by the MDI parent then they should have an UnloadMode of 4, vbFormMDIForm) followed by each of their Unload events.

Hope this helps

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.

 
I'm not questioning what you say, but in earlier testing I added Stop statements in both the Form_Unload and Form_QueryUnload events of the MDI children and then closed the parent and it never reaches either of the Stop statements.

I then thought it might be because I've got an End statement in the Form_Unload event of the parent, but if I take that out the program never closes when the user clicks the X (it disappears but continues to run).

- Andy
___________________________________________________________________
If you think nobody cares you're alive, try missing a couple of mortgage payments
 
What happens when you close the MDI form?

The order of events should occur as follows:

MDI - QueryUnload
Child1 - QueryUnload
Child2 - QueryUnload
Subsequent Children - QueryUnload

MDI - Unload
Child1 - Unload
Child2 - Unload
Subsequent Children - Unload

Is there anything in the MDI's QueryUnload event that would affect subsequent events?

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.

 
Actually it is:

Child1 - Unload
Child2 - Unload
Subsequent Children - Unload
and then MDI - Unload

>Is there anything in the MDI's QueryUnload event that would affect subsequent events?
Not really, unless you set the Cancel to vbTrue, as the forms unload between the MDI_QueryUnload and the MDI_Unload.

But this would keep the app running:

Private Sub MDIForm_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Unload MyNonChildForm
If MyNonChildForm.Visible=False then
End If
End Sub
=============================

AndyGroom, there are some reasons this will happen, and usually it has to do with certain objects not unloading.

If you have for instance, a non-MDIChild form loaded (they do not even have to be shown), it will not get automatically unloaded, and when your application ends, it will disappear but may be still running.

To begin with, test this:
1. Start a new Project. Should have already by default a Form1 added.
2. Add a MDI Form
3. Set the Start Object to the MDI Form (Menu-Project-Properties-Start Object)
4. Add a new Form (Form2) and set it's MDIChild property to TRUE

5. Add this code to the MDI:
Code:
Option Explicit

Private Sub MDIForm_Load()
    Load Form1
    Load Form2
End Sub

Private Sub MDIForm_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    Debug.Print "Event MDI QueryUnload"
End Sub

Private Sub MDIForm_Unload(Cancel As Integer)
    Debug.Print "Event MDI Unload"
    Dim frm As VB.Form
    For Each frm In Forms
        If (TypeOf frm Is VB.MDIForm) = False Then Debug.Print "Still loaded: " & frm.Name
    Next frm
End Sub
6. Add this to Form1:
Code:
Option Explicit

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Debug.Print "Event Form_QueryUnload non-child "
End Sub

Private Sub Form_Unload(Cancel As Integer)
Debug.Print "Event Form_Unload non-child"
End Sub
7. Add this to Form2
Code:
Option Explicit

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Debug.Print "Event Form_QueryUnload child "
End Sub

Private Sub Form_Unload(Cancel As Integer)
Debug.Print "Event Form_Unload child"
End Sub
8. Run the project and then close the MDI. You will see that Form1 is still running. In the Debug Window you will see that Form1 didn't unload, and you will need to hit the Stop button on the IDE toolbar.

To make sure that at least all non-MdiChild forms are unloaded, use this in the MDI_QueryUnload:

If (TypeOf frm Is VB.MDIForm) = False Then Debug.Print "Still loaded: " & frm.Name
Unload frm

Now you will see that Form1 got unloaded and the app will actually end.




 
SBerthold - You caught me there, my explanation was a bit off [blush]

>Is there anything in the MDI's QueryUnload event that would affect subsequent events?
Not really, unless you set the Cancel to vbTrue, as the forms unload between the MDI_QueryUnload and the MDI_Unload.
What I meant by my question there was not a general question about unloading behaviour, I was asking if Andy had anything specific in his MDI_QueryUload event that would stop the child forms unloading.

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.

 
We'll both get there in the end (and hopefully Andy as well) [smile]

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.

 
Thanks for all the replies.

I think I've narrowed down the problem although I haven't solved it yet. The actual order of events firing does seem to match HarleyQuinn's outline, ie that first of all the QueryUnload events all fire followed by Unload events.

I think my problem was that I had an End statement in the MDIParent's QueryUnload event instead of in the Unload event, so the childrens' QueryUnload events never got chance to fire.

However, when I move the End statement to the MDIParent's Unload event instead of QueryUnload, the user has to click the 'X' twice to close the application - the first click closes all the children and the second click closes the app, but I think I can track that down.

- Andy
___________________________________________________________________
If you think nobody cares you're alive, try missing a couple of mortgage payments
 
>I think my problem was that I had an End statement in the MDIParent's QueryUnload

Ah - you beat me to it. Last night I was going to ask whether you possibly had an End statement lying around anywhere. And then I decided I needed sleep more ...
 
And after a shocking day yesterday of getting very easy things completely wrong when posting solutions (no idea why [ponder] but I seem a bit better today again [wink]) I managed to elude to something correctly [smile]

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.

 


But he first said in his second post:
I then thought it might be because I've got an End statement in the Form_Unload event of the parent

However, yes, in the QueryUnload that will also cause the problem.

In all, as I stated, some objects are not getting unloaded.
 
I'd agree (with one caveat).

In all, as I stated, some objects are not getting unloaded. Properly

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top