Page 1 of 1

End Application ( for Antonio! )

Posted: Thu Apr 10, 2008 11:17 am
by JC
Hi friends!!

What is the best way to end any application?

I'm using this way:

Code: Select all

PostQuitMessage (0)
__quit ()
Thanks at all!

Posted: Thu Apr 10, 2008 12:06 pm
by Antonio Linares
The right way to end the application is to :End() the main window (or dialog):

oWnd:End()

Posted: Thu Apr 10, 2008 12:16 pm
by Roger Seiler
You don't actually have to use QUIT. Depending on circumstances, there may be a better way...

Usually there are housekeeping chores that should be done just before the app shuts down, like closing and open DLL's, closing all open databases, destroying all resources, updating the app's .ini file with user preferences, and clearing memory. Plus on a network where you have granted your user limited concurrent user rights that are overseen by some type of concurrent-user-counter, then you need to decrement the number of users online so someone else can access the user right that is being vacated.

So, depending on how complex the app is, shutting it down properly can be complicated.

Fortunuately, Clipper-Harbour-xHarbour offers an easy way to do all this:

the automatically executed EXIT PROCEDURE whatevername()

When the user clicks on the big X in the upper right hand corner of the apps main window, or the app executes oWnd:End() for the main window, the Clipper-compatible program will automatically look for an EXIT PROCEDURE to execute before shutting down the app, and so you put into that proc all (or most) of he housekeeping chores that need to be done.

If you follow standard Windows programming practice and put an Exit option at the bottom of your File menu, then you can close the app in two steps, which is often advisable because it gives you more control over how things get shut down. The first step is a pre-exit procedure with any name you like, such as PROCEDURE PreExit(), where some optional housekeeping steps get done (like a closing-dialog with the user) and where at the bottom of it you put oWnd:End() which automatically calls EXIT PROCEDURE, where you put the mandatory housekeeping steps that absolutely must be done in order to close things down properly.

So here is how I do it:

1. bottom option of File menu:

MENU ITEM "Exit" ;
ACTION PreExit();
MESSAGE "Exit this program."

// I also may call PreExit() from other places within the app.

2. PROCEDURE PreExit()
// An advantage of this proc is that it can be called from anywhere
// within the app to start the closedown procedure - for example, if
// you have a free demo policy that after 30 days won't let the user
// run the app without buying an unlock code. In that case, your demo
// management code automatically calls PreExit() which then displays
// a "demo period expired" message and then shuts down the app by
// calling oWndEnd() which in turn automatically executes EXIT PROC
// to do the mandatory chut-down items.

IF lDemoExpired .AND. !lUnlocked
MsgInfo("Demo period has expired. Please purchase unlock code")
ENDIF

oBrush:End() // If a brush used
oWnd:End()

RETURN
*--------------

3. the Exit Proc:

EXIT PROCEDURE KillApp() // "KillApp()" can't be called by your code,
// but EXIT PROCEDURE is automatically
// called by oWnd:End() and click on X.

// Mandatory shut-down steps...

// Write user pref's to the .ini file (app maximized/windowized, etc)

// Decrement the online-users count

// Close any open DLL's

ResAllFree() // end any open resources
CLOSE DATABASES
CLEAR MEMORY

RETURN
*-----------

As usual, I've probably told you more than you wanted to know, and I'm sure some FWH power-users like Enrico or James may have some better ideas, but maybe some of this is helpful.

- Roger

Posted: Thu Apr 10, 2008 12:22 pm
by JC
Antonio Linares wrote:The right way to end the application is to :End() the main window (or dialog):

oWnd:End()
Thanks Linares but, something it's happening... I using a user function for a dialog confirmation to end the application.

When I confirm, the main window closes, but the confirmation dialog remains open. And the .exe still appear in the manager tasks of windows!!

You understanding?

Posted: Thu Apr 10, 2008 12:31 pm
by Antonio Linares
Júlio,

Please try to provide me a small PRG that reproduces the way you are doing it. Thanks,

Posted: Thu Apr 10, 2008 12:34 pm
by Antonio Linares
Here you have a working sample:

Code: Select all

#include "FiveWin.ch"

function Main()

   local oWnd

   DEFINE WINDOW oWnd TITLE "Test"

   ACTIVATE WINDOW oWnd ;
      VALID ConfirmExit()

return nil

function ConfirmExit()

   local oDlg, lExit := .F.

   DEFINE DIALOG oDlg TITLE "Please confirm"

   @ 1, 1 SAY "Do you want to exit ?"

   @ 3, 1 BUTTON "Yes" ACTION ( oDlg:End(), lExit := .T. )

   @ 3, 8 BUTTON "No" ACTION oDlg:End()

   ACTIVATE DIALOG oDlg CENTERED

return lExit

Posted: Thu Apr 10, 2008 12:41 pm
by JC
Antonio Linares wrote:Júlio,

Please try to provide me a small PRG that reproduces the way you are doing it. Thanks,
Linares... is here -> http://rapidshare.com/files/106356753/app.prg.html


The function msgDialogBox() only creates a dialog with two buttons for confirmation.
It's only a more elegant way to display any confirmation messages.

The function freeDlg( oDlg ), only execute this things:

oDlg:bValid := .T.
oDlg:end()
oDlg := NIL

Posted: Thu Apr 10, 2008 12:48 pm
by Antonio Linares
Júlio,

The example that I have provided you, it can be built and tested. Have you tested it ?

Your provided PRG can't be built here (missing resources, variables and functions).

Please understand that in order to provide tech support we need your cooperation providing ready to be built PRG code, thanks

Posted: Thu Apr 10, 2008 12:51 pm
by JC
Antonio Linares wrote:Júlio,

The example that I have provided you, it can be built and tested. Have you tested it ?

Your provided PRG can't be built here (missing resources, variables and functions).

Please understand that in order to provide tech support we need your cooperation providing ready to be built PRG code, thanks
Ok Antonio! I go to do!

PS.: In English it is easier for me ;)

Posted: Thu Apr 10, 2008 2:51 pm
by JC
Antonio Linares wrote:The right way to end the application is to :End() the main window (or dialog):

oWnd:End()
Hi Antonio...

I created an example, but he was not representing exactly the same situation ... Then I have studied more my source code and achieve resolve as follows:

Code: Select all

FUNCTION endApp( lConfirm, lForce )

LOCAL lEndApp := .F.
LOCAL nAllWin  := 0
LOCAL aAllWin  := {}
LOCAL nPos      := 0

DEFAULT lConfirm := .T.
DEFAULT lForce     := .F.


IF lConfirm
   lEndApp := msgDialogBox( "Finish application?", "System", MSG_YESNO )
ENDIF

IF lEndApp .OR. lForce

    oSIS_Conection:freeResult( .T. )
    oSIS_Conection:clean()
    oSIS_Conection:disconnect()

    oSIS_Conexao := NIL

    resAllFree()

ENDIF

IF lForce

   ( getWnd() ):bValid := {|| .T. }

   nAllWin := nWindows()
   aAllWin := getAllWin()

   FOR nPos := 1 TO nAllWin
       aAllWin[nPos]:end()
   NEXT

   ( getWnd() ):end()

ENDIF

RETURN( lResultado )


RETURN( lEndApp )
The getWnd() function:

Code: Select all

FUNCTION getWnd()
RETURN( oWndFromhWnd( findWindow( 0, "window title" ) ) )