FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Mutually calling DIALOGs
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 07:47 PM
What is the correct way to close mutually calling DIALOGs? Try the following sample:

#include "Fivewin.ch"


FUNCTION MAIN()

    TEST1()

    RETURN NIL


STATIC FUNCTION TEST1()

    LOCAL oDlg

    DEFINE DIALOG oDlg;
           TITLE "Test1"

    @ 1, 1 BUTTON "Switch to test2";
           ACTION ( oDlg:End(), TEST2() )

    ACTIVATE DIALOG oDlg;
             CENTER

    ? "Exiting from test1"

    RETURN NIL


STATIC FUNCTION TEST2()

    LOCAL oDlg

    DEFINE DIALOG oDlg;
           TITLE "Test2"

    @ 1, 1 BUTTON "Switch to test1";
           ACTION ( oDlg:End(), TEST1() )

    ACTIVATE DIALOG oDlg;
             CENTER

    ? "Exiting from test2"

    RETURN NIL


Thanks for any help.

EMG
Posts: 219
Joined: Mon Dec 26, 2005 07:25 PM
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 08:06 PM
Try this:

FUNCTION MAIN()

TEST1( 0 )

RETURN NIL


STATIC FUNCTION TEST1( hWnd )

LOCAL oDlg

IF hWnd # 0
PostMessage(hWnd,WM_CLOSE)
ENDIF


DEFINE DIALOG oDlg;
TITLE "Test1"

@ 1, 1 BUTTON "Switch to test2";
ACTION TEST2( oDlg:hWnd )

ACTIVATE DIALOG oDlg;
CENTER

? "Exiting from test1"

RETURN NIL


STATIC FUNCTION TEST2( hWnd )

LOCAL oDlg

IF hWnd # 0
PostMessage(hWnd,WM_CLOSE)
ENDIF


DEFINE DIALOG oDlg;
TITLE "Test2"

@ 1, 1 BUTTON "Switch to test1";
ACTION TEST1( hWnd )

ACTIVATE DIALOG oDlg;
CENTER

? "Exiting from test2"

RETURN NIL

You could use PostMessage() or directly SendMessage().
Nos Gusta Programar
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 08:20 PM

Unfortunately that doesn't solve the problem. :-(

EMG

Posts: 105
Joined: Fri Jun 09, 2006 03:27 PM
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 09:00 PM

I have done something similar with Dialogs that are called from multiple locations. I use STATIC oDlg1, oDlg2 etc and in any given function use oDlg1:end() etc. so that I can close any dialog from inside any function (for those dialogs that must be handled that way).

Hope that helps.

Regards,

Greg Gammon
Posts: 219
Joined: Mon Dec 26, 2005 07:25 PM
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 09:02 PM
Effectivly it doesn't work. But this works correctly:

FUNCTION MAIN()

TEST1()

RETURN NIL


STATIC FUNCTION TEST1()

LOCAL oDlg
LOCAL lGo := .F.

DEFINE DIALOG oDlg;
TITLE "Test1"

@ 1, 1 BUTTON "Switch to test2";
ACTION (lGo := .T., oDlg:End())

ACTIVATE DIALOG oDlg CENTER
? "Exiting from test1"

IF lGo
TEST2()
ENDIF


RETURN NIL


STATIC FUNCTION TEST2()

LOCAL oDlg
LOCAL lGo := .F.
DEFINE DIALOG oDlg;
TITLE "Test2"

@ 1, 1 BUTTON "Switch to test1";
ACTION (lGo := .T., oDlg:End())

ACTIVATE DIALOG oDlg;
CENTER

? "Exiting from test2"

IF lGo
TEST1()
ENDIF


RETURN NIL

Dialogs don't mutally call each other but it's works fine. If you click the button the dialog closes it self and the other opens, if you click any "X" top right button the dialog closes without calling another dialog.
(Excuse my english)
Nos Gusta Programar
Posts: 105
Joined: Fri Jun 09, 2006 03:27 PM
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 09:14 PM

Actually i went back and looked at my code and its very similar to what manuramos has said....

ACTION oDlg:end(), lNext := .t.
END DIALOG

IF lNext
nextfunction()
ENDIF

yep...thats what I did too. Its a winner. I used STATIC dialog references on another issue.
G

Regards,

Greg Gammon
Posts: 663
Joined: Mon Dec 05, 2005 11:22 PM
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 09:22 PM

You don't want to get down to many levels. How about this?

FUNCTION MAIN()
local bBlock := { || test1() }
do while bBlock != nil
bBlock := eval( bBlock )
enddo

RETURN NIL

STATIC FUNCTION TEST1()
local bBlock

LOCAL oDlg

DEFINE DIALOG oDlg;
TITLE "Test1"

@ 1, 1 BUTTON "Switch to test2";
ACTION ( bBlock := { || test2() }, oDlg:End() )

ACTIVATE DIALOG oDlg;
CENTER

? "Exiting from test1"

RETURN( bBlock )

STATIC FUNCTION TEST2()
local bBlock

LOCAL oDlg

DEFINE DIALOG oDlg;
TITLE "Test2"

@ 1, 1 BUTTON "Switch to test1";
ACTION ( bBlock := { || test1() }, oDlg:End() )

ACTIVATE DIALOG oDlg;
CENTER

? "Exiting from test2"

RETURN( bBlock )

Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 09:28 PM

This is on oversimplification and doesn't still solves my problem, sorry. I actually don't know what is the next function to call inside TEST1() and TEST2().

EMG

Posts: 663
Joined: Mon Dec 05, 2005 11:22 PM
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 09:51 PM

It seems to me that if you call test1() from test2(), then test2() from test1(), etc you will keep getting farther down the call stack. You either need to pass a codeblock along to an arbitrator or use the code like I sent above.

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Mutually calling DIALOGs
Posted: Fri Jul 07, 2006 06:53 AM

Enrico,

IMO there is nothing wrong with your code. You are managing modal dialogboxes so the execution waits until you return from the called function.

Modal dialogboxes stop the execution (its a Windows API modal called function) until you exit from them.

As Gale said, the stack will grow and grow until you don't exit from them. The only solution for this is to use non modal dialog boxes.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Mutually calling DIALOGs
Posted: Fri Jul 07, 2006 09:31 AM
Thank you. This is a working sample, at last:

#include "Fivewin.ch"


FUNCTION MAIN()

    LOCAL oWnd

    DEFINE WINDOW oWnd;
           FROM 1000, 1000 TO 1000, 1000

    ACTIVATE WINDOW oWnd;
             ON INIT ( oWnd:Hide(), TEST1( oWnd ) )

    RETURN NIL


STATIC FUNCTION TEST1( oWnd )

    LOCAL oDlg

    LOCAL lQuit := .T.

    DEFINE DIALOG oDlg;
           TITLE "Test1"

    @ 1, 1 BUTTON "Switch to test2";
           ACTION ( lQuit := .F., oDlg:End(), TEST2( oWnd ) )

    ACTIVATE DIALOG oDlg;
             VALID ( MSGINFO( "Exiting from test1" ),;
                     IF( lQuit, oWnd:End(), ),;
                     .T. );
             CENTER NOMODAL

    ? "Immediately exit from test1"

    RETURN NIL


STATIC FUNCTION TEST2( oWnd )

    LOCAL oDlg

    LOCAL lQuit := .T.

    DEFINE DIALOG oDlg;
           TITLE "Test2"

    @ 1, 1 BUTTON "Switch to test1";
           ACTION ( lQuit := .F., oDlg:End(), TEST1( oWnd ) )

    ACTIVATE DIALOG oDlg;
             VALID ( MSGINFO( "Exiting from test2" ),;
                     IF( lQuit, oWnd:End(), ),;
                     .T. );
             CENTER NOMODAL

    ? "Immediately exit from test2"

    RETURN NIL


EMG

Continue the discussion