ON SHUTDOWN DO App_ShutDown in main_prg_name.FXPThen I have the following code in my MAIN PRG file:
PROCEDURE App_Shutdown LOCAL loForm, llKilled #IF USING_TOP_LEVEL_FORM IF TYPE('goApp') = 'O' AND NOT ISNULL(goApp) loForm = goApp.GetTopLevelFormRef() llKilled = goApp.KillEvents() ENDIF #ENDIF IF NOT llKilled CLEAR EVENTS ENDIF IF VARTYPE(loForm) = 'O' AND NOT ISNULL(loForm) loForm.RELEASE() ENDIF KillObjects() ON ERROR ON SHUTDOWN ENDPROC PROCEDURE KillObjects IF TYPE('goDataMgr') = 'O' AND NOT ISNULL(goDataMgr) goDataMgr.RELEASE() ENDIF IF TYPE('goMsgSrvr') = 'O' AND NOT ISNULL(goMsgSrvr) goMsgSrvr.RELEASE() ENDIF IF TYPE('goConMgr') = 'O' AND NOT ISNULL(goConMgr) goConMgr.RELEASE() ENDIF IF TYPE('goErrors') = 'O' AND NOT ISNULL(goErrors) goErrors.RELEASE() ENDIF IF TYPE('goApp') = 'O' AND NOT ISNULL(goApp) goApp.Release() ENDIF ENDPROCI use top level forms, but if you do not, set my USING_TOP_LEVEL_FORM constant to .F. You can place this constant value in your own header (.H) file or at the top of your MAIN PRG file. I also add a menu to my apps, where I have an Exit option under the "File" menu pad. The command for the Exit option is just simply CLEAR EVENTS. In the UNLOAD of my Top Level Form, I have a goApp.KillEvents() command.
PROCEDURE KillEvents IF THIS.lKilled RETURN ENDIF IF THIS.ReleaseObjects() CLEAR EVENTS THIS.lKilled = .T. ELSE RETURN .F. ENDIF ENDPROC PROTECTED PROCEDURE ReleaseObjects IF THIS.FormList.COUNT = 0 RETURN .T. ENDIF LOCAL lnItem, loForm lnItem = 0 IF NOT EMPTY(THIS.FormList.ActiveFormHwnd) lnItem = THIS.FormList.GETKEY(THIS.FormList.ActiveFormHwnd) ENDIF IF lnItem > 0 loForm = THIS.FormList.ITEM(lnItem) IF loForm.SHOWWINDOW = 2 *!* Do not close the top-level form LOOP ENDIF IF loForm.WINDOWTYPE = 1 *!* if the active form is modal, do not shutdown RETURN .F. ENDIF ENDIF LOCAL lnI, lnKount, loForm lnKount = THIS.FormList.COUNT FOR lnI = lnKount TO 1 STEP -1 loForm = THIS.FormList.ITEM(lnI) loForm.QUERYUNLOAD() ENDFOR ENDPROCThis class has a property (FormList) that is a collection object where each item is an object reference to an open form. I just process those to close each form. My Form class uses the QUERYUNLOAD to do some checking to see if the form can actually be closed. If it can be closed, then my QUERYUNLOAD calls the form's RELEASE method. Since VFP6 does not have a collection object, you can use the _screen.forms collection and _screen.formcount to loop through the forms to close them. Just start at formcount and step -1 to process the open forms.