Page 1 of 1
Mutually calling DIALOGs
Posted: Thu Jul 06, 2006 7:47 pm
by Enrico Maria Giordano
What is the correct way to close mutually calling DIALOGs? Try the following sample:
Code: Select all
#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
Posted: Thu Jul 06, 2006 8:06 pm
by manuramos
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().
Posted: Thu Jul 06, 2006 8:20 pm
by Enrico Maria Giordano
Unfortunately that doesn't solve the problem.
EMG
Posted: Thu Jul 06, 2006 9:00 pm
by Greg Gammon
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.
Posted: Thu Jul 06, 2006 9:02 pm
by manuramos
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)
Posted: Thu Jul 06, 2006 9:14 pm
by Greg Gammon
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
Posted: Thu Jul 06, 2006 9:22 pm
by Gale FORd
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 )
Posted: Thu Jul 06, 2006 9:28 pm
by Enrico Maria Giordano
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
Posted: Thu Jul 06, 2006 9:51 pm
by Gale FORd
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.
Posted: Fri Jul 07, 2006 6:53 am
by Antonio Linares
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.
Posted: Fri Jul 07, 2006 9:31 am
by Enrico Maria Giordano
Thank you. This is a working sample, at last:
Code: Select all
#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