program not fully closing
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 30

Thread: program not fully closing

  1. #1
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303

    program not fully closing

    a lot of times after exiting my app it doesn't fully close. it will appear to close and is removed from the taskbar, but when i hit cntrl+alt+del it shows it's still running. it only happens in the compiled exe. i'm using the code that the wizard generated for exiting:

    Code:
    Dim i As Integer
        'close all sub forms
        For i = Forms.count - 1 To 1 Step -1
            Unload Forms(i)
        Next
    seems like i also tried putting an End statement after that too, just in case, but it didn't help.

    the reason this is a problem is for when you install a new version or something and the file is in use and can't be overwritten (well, i can have it foribly close the program, but still), and when i try to re-compile the app after testing the exe out and i hafta ctrl+alt+del it first.
    Last edited by Cimperiali; June 19th, 2003 at 04:21 AM.

  2. #2
    Join Date
    Jan 2003
    Location
    7,107 Islands
    Posts
    2,487
    Well, maybe because the forms collection is zero-based so

    Code:
    Dim i As Integer
    'close all sub forms
    For i = Forms.count - 1 To 0 Step -1
       Unload Forms(i)
    Next
    Or try accessing by collection object

    Code:
    Dim f As Form
    
    'close all sub forms
    For each f in Forms
      Unload f
    Next f
    Last edited by Cimperiali; June 19th, 2003 at 04:22 AM.
    Busy

  3. #3
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303
    you sure? cause the wizard made the code, and you'd think it'd be right... i'll try it tho.

  4. #4
    Join Date
    Jan 2003
    Location
    Albany, NY
    Posts
    82

    Create your own collection

    Dim FormCol as Collection
    ...
    ...
    Dim x as form1
    Formcol.add X
    Dim y as Form2
    Formcol.add Y
    ....
    ...
    dim Frm as Form/Object
    For each Frm in formcol
    unload frm
    next

    You can also add other objects into the collection to cenralize your cleanup.
    Your code can only be as good as your algorithm.

  5. #5
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303
    oh for the love of god.... even this doesn't work....



    Code:
    Public Sub CloseProgram()
        ClosingNow = True
            
        Dim FormCol As Collection
        Dim Frm As Form
    
        Dim i As Integer
        For i = 1 To 56
            Select Case i
                Case 1
                    Set Frm = frmFont
                Case 2
                    Set Frm = frmHR
                .....
                Case 55
                    Set Frm = frmMain
                Case 56
                    Set Frm = fMainForm
            End Select
            
            FormCol.Add Frm
        Next
    
    
        For Each Frm In FormCol
            Unload Frm
            Set Frm = Nothing
        Next
    
    End Sub

    (it's in a module)











    ============edit===========
    ok, found out after tracing through that raises an error and exits the sub at the FormCol.Add line.

    but i also tried this:

    Code:
    Public Sub CloseProgram()
        ClosingNow = True
        
        On Error Resume Next
            
        Dim Frm As Form
        
        For Each Frm In Forms
            Unload Frm
            Set Frm = Nothing
        Next
    End Sub

    and it also raises an error after the 2nd Frm, which is why i added the On Error line, but either way it still doesn't work. you would think this would be simple, my god...
    Last edited by gnznroses; June 19th, 2003 at 12:20 AM.

  6. #6
    Join Date
    May 2003
    Location
    Australia
    Posts
    155
    Hi,

    You'd think it'd be all nice and straight forward huh

    Obviously, code written properly should work, but sometimes your code can be a pain in the butt and work against you, especially if you have timers and events flying all over the place.

    One little interesting thing to note, is that if any of your code refers to a particular form, VB will automatically load that form to access the property if its not loaded. So if you have a timer that refers to a form, and you click on a button to shut down your app, and you unload all loaded forms like you have been trying to do, if your timer kicks in while you are in the process of this unloading For Loop, and it refers to a form that has already been unloaded, it will automatically load it again for you (how polite)

    This is one example of how things can get screwy when you have complicated event and timer driven code.

    This might not be the same problem you are having, but the solution that I used to get around the above problem should work here (providing your unload code is actually ok).

    Create a sub that unloads all forms in the forms collection. In the beginning of that sub, set a global/public flag gbShutDown = True. Then at the beginning of the Form_Load event of every form, check that this flag has not been set. If it has, then we are in the process of shutting down, so unload the form.

    Another thing that might be causing your problem, is if you have this ShutDown sub in a module called from a form ... if you have unloaded the form, where does the module code return to? Back to the form, so VB loads it automatically again for you ... or something worse

    Code:
    Private Sub_FormLoad()
    
      If gbShutDown Then
        Unload Me
        Exit Sub
      End If
    
      ... ' run normal form loadup code here
    
    End Sub
    
    Private Sub ShutDown()
    
      Dim iCount As Integer
    
      ' set our shutdown flag
      gbShutDown = True
        
      ' unload all forms except for the current form
      For iCount = (Forms.Count - 1) To 0 Step -1
        If Not Forms(iCount) Is Me Then
          Unload Forms(iCount)
        End If
      Next
    
      ' do the current form last
      Unload Me
    
    End Sub
    See how you go with this.

    Cheers,
    Tinbum747
    Zen-Programming:

    If a compiler beeps in the IDE forest, and nobody hears it, was there really a bug?

  7. #7
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    If it raise errors...

    Code:
    Public Sub CloseProgram()
        ClosingNow = True
         
        'On Error Resume Next
             
        Dim Frm As Form
         
        For Each Frm In Forms
            Unload Frm
            'better you do this last at end only, outside the cycle 
            Set Frm = Nothing
        Next
    End Sub
    it also raises an error after the 2nd Frm
    is because the form you tried to unload...is already unloaded
    Did you refer twice to same?
    In any case, set frm to nothing only at end (out of cycle)
    Like in this example:
    Code:
    Public Sub CloseProgram(ByVal frmPointer As Long)
        'ClosingNow = True
          
        'On Error Resume Next
              
        Dim Frm As Form
          
        For Each Frm In Forms
          'do not unload the caller
          Debug.Print Frm.Name
          Debug.Print ObjPtr(Frm)
           
          If ObjPtr(Frm) <> frmPointer Then
            Unload Frm
          End If
            'better you do this last at end only, outside the cycle
             
        Next
        Set Frm = Nothing
    End Sub
    And to call it in a form you can do
    Code:
    Private Sub Form_Unload()
       Form2.Show
       Dim frmx As Form
       Set frmx = New Form1
       frmx.Show
       'close all but this one which 
       'is already unloading
       CloseProgram (ObjPtr(Me))
        
    End Sub
    BY the way: if you ahave code in execution (ina loop, or in a timer) or if a form is waiting for a component answer, or if you are playing with some Api calls, that form may not unload.... Be sure you free all referenced objects and stops all loop and timers...
    Last edited by Cimperiali; June 19th, 2003 at 04:38 AM.
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  8. #8
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    For your specific matter...

    If you put a call to it in unload events of forms, it may happen you call the sub more than once while it is executing.
    You can prevent multiple calls before the first is ended this way:
    Code:
    Public Sub CloseProgram(ByVal frmPointer As Long)
         
       Static bClosing As Boolean
                   
        Dim Frm As Form
        If Not bClosing Then
          bClosing = True
          For Each Frm In Forms
            'do not unload the caller
            If ObjPtr(Frm) <> frmPointer Then
              Unload Frm
            End If
              'better you do this last at end only, outside the cycle
                
          Next
          Set Frm = Nothing
        End If
    End Sub
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  9. #9
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303

    Re: For your specific matter...

    Originally posted by Cimperiali
    If you put a call to it in unload events of forms, it may happen you call the sub more than once while it is executing.
    yeah, i've got the ClosingNow variable there for that reason.

  10. #10
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303
    Originally posted by Tinbum747
    Hi,

    You'd think it'd be all nice and straight forward huh

    Obviously, code written properly should work, but sometimes your code can be a pain in the butt and work against you, especially if you have timers and events flying all over the place.

    One little interesting thing to note, is that if any of your code refers to a particular form, VB will automatically load that form to access the property if its not loaded. So if you have a timer that refers to a form, and you click on a button to shut down your app, and you unload all loaded forms like you have been trying to do, if your timer kicks in while you are in the process of this unloading For Loop, and it refers to a form that has already been unloaded, it will automatically load it again for you (how polite)

    This is one example of how things can get screwy when you have complicated event and timer driven code.

    This might not be the same problem you are having, but the solution that I used to get around the above problem should work here (providing your unload code is actually ok).

    Create a sub that unloads all forms in the forms collection. In the beginning of that sub, set a global/public flag gbShutDown = True. Then at the beginning of the Form_Load event of every form, check that this flag has not been set. If it has, then we are in the process of shutting down, so unload the form.

    Another thing that might be causing your problem, is if you have this ShutDown sub in a module called from a form ... if you have unloaded the form, where does the module code return to? Back to the form, so VB loads it automatically again for you ... or something worse

    Code:
    Private Sub_FormLoad()
    
      If gbShutDown Then
        Unload Me
        Exit Sub
      End If
    
      ... ' run normal form loadup code here
    
    End Sub
    
    Private Sub ShutDown()
    
      Dim iCount As Integer
    
      ' set our shutdown flag
      gbShutDown = True
        
      ' unload all forms except for the current form
      For iCount = (Forms.Count - 1) To 0 Step -1
        If Not Forms(iCount) Is Me Then
          Unload Forms(iCount)
        End If
      Next
    
      ' do the current form last
      Unload Me
    
    End Sub
    See how you go with this.

    Cheers,
    Tinbum747

    thanks. i had thought about that, but i was just hoping unloading the form would get it done even if it did go through the load event of each form i'm trying to unload. guess not tho.

  11. #11
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303
    *sigh*, well, this don't work (it's basically a combination of both you guys' suggestions):

    Code:
    Private Sub Form_Unload(Cancel As Integer)
        If ClosingNow = True Then Unload Me: Exit Sub
    
        On Error Resume Next
        
        ClosingNow = True
        
        'unload all forms except for the current form
        Dim iCount As Integer
        For iCount = (Forms.count - 1) To 0 Step -1
            If Not Forms(iCount) Is Me Then
                Unload Forms(iCount)
            End If
        Next
        
        ' do the current form last
        Unload Me
    
    End Sub




    that's the main form. i also put the "If ClosingNow = True Then Unload Me: Exit Sub" line in every form's Load event.

    i don't have any timers or anything running.


    oh, and does it help to know the wizrd uses the Sub_Main, like this:

    Sub Main()
    Set fMainForm = New frmMain '<--the main form
    fMainForm.Show
    End Sub
    Last edited by gnznroses; June 19th, 2003 at 01:00 PM.

  12. #12
    Join Date
    Feb 2003
    Location
    Greece
    Posts
    533

    freeing up other resources

    After you unload all the dynamic data you used (objects, data, etc) you have to ensure that you've released completely all the system resources you used in any way.

    Sometimes api-calls (example) have an Init_State and a Done_State which you must use to terminate any other (invisible) resources captured during the program execution. If not, the result could be a pseydo-end of your program by keeping the app title in the task manager report as you are saying your self.

    Anyway, all the methods i saw above my msg is correct and depends of course of the complete program you made.
    - Better live in the digital world -

  13. #13
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303
    is there any way to just forcibly kill the program? like amybe the TerminateProcess API?

  14. #14
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726
    you can use

    END

    command. But I am reading you did in first trying...


    Better you understand why it does nopt close normally.
    Remember:

    If Not Forms(iCount) Is Me Then
    is not the same as testing with ObjPtr(theForm).
    moreover, if you are in a bas module, Me keyword will not work: it should rise an error...

    In any case, you sure you do not have circular references?
    Last edited by Cimperiali; June 19th, 2003 at 01:52 PM.
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  15. #15
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303
    ok, so i tried this....

    in a module:

    Code:
    Public Sub CloseProgram(ByVal frmPointer As Long)
           
        Dim Frm As Form
        
        If Not ClosingNow Then
            ClosingNow = True
            
            For Each Frm In Forms
                Debug.Print Frm.Name
                Debug.Print ObjPtr(Frm)
        
                'do not unload the caller
                If ObjPtr(Frm) <> frmPointer Then
                    Unload Frm
                End If
            Next
            
          Set Frm = Nothing
        End If
        
    End Sub



    in my main form:
    Code:
    CloseProgram (ObjPtr(Me))


    and in every form's load event:
    Code:
    If ClosingNow = True Then Unload Me: Exit Sub





    still doesn't work. and there are no timers or any other code running. it's just an html editor, nothing that complicated.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This a Codeguru.com survey!


On-Demand Webinars (sponsored)