Mutually calling DIALOGs

Mutually calling DIALOGs

Postby Enrico Maria Giordano » Thu Jul 06, 2006 7:47 pm

What is the correct way to close mutually calling DIALOGs? Try the following sample:

Code: Select all  Expand view
#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
User avatar
Enrico Maria Giordano
 
Posts: 8710
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby manuramos » Thu Jul 06, 2006 8: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
manuramos
 
Posts: 219
Joined: Mon Dec 26, 2005 7:25 pm
Location: Jerez de la Frontera (Spain)

Postby Enrico Maria Giordano » Thu Jul 06, 2006 8:20 pm

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

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8710
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby Greg Gammon » Thu Jul 06, 2006 9: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.
User avatar
Greg Gammon
 
Posts: 105
Joined: Fri Jun 09, 2006 3:27 pm
Location: Bryan, Texas

Postby manuramos » Thu Jul 06, 2006 9: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
manuramos
 
Posts: 219
Joined: Mon Dec 26, 2005 7:25 pm
Location: Jerez de la Frontera (Spain)

Postby Greg Gammon » Thu Jul 06, 2006 9: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
User avatar
Greg Gammon
 
Posts: 105
Joined: Fri Jun 09, 2006 3:27 pm
Location: Bryan, Texas

Postby Gale FORd » Thu Jul 06, 2006 9: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 )
Gale FORd
 
Posts: 663
Joined: Mon Dec 05, 2005 11:22 pm
Location: Houston

Postby Enrico Maria Giordano » Thu Jul 06, 2006 9: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
User avatar
Enrico Maria Giordano
 
Posts: 8710
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby Gale FORd » Thu Jul 06, 2006 9: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.
Gale FORd
 
Posts: 663
Joined: Mon Dec 05, 2005 11:22 pm
Location: Houston

Postby Antonio Linares » Fri Jul 07, 2006 6: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42077
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Enrico Maria Giordano » Fri Jul 07, 2006 9:31 am

Thank you. This is a working sample, at last:

Code: Select all  Expand view
#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
User avatar
Enrico Maria Giordano
 
Posts: 8710
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: cmsoft, nageswaragunupudi and 94 guests