Urgent help

Urgent help

Hi, everyone.
Now I am developing a Win32API project based on dialog. I want perform a 'BACK' button as following:

Subroutine Dialog_A ()
...
type(dialog) dlg_a
use dflogm
implicit none
include 'resource.fd'

! Initize a modal dlg_a
! There is an undefined 'OK' button in this dialog
lret=dlginit(IDD_a, dlg_a)
lret=dlgset(..
...
lret=modal(dlg_a)
...
select case (choice)
...
case(5)
call dialog_B()
end select
call Dlguninit(dlg_a)
end subroutine dialog_a

Subroutine Dialog_b ()
use dflogm
implicit none
include 'resource.fd'
external dlgb_back
type(dialog) dlg_b
...
lret=dlginit(IDD_B, dlg_b)

!The other 'OK' button in this dialog is not defined
lret=dlgsetsub(dlg_b, ID_B_BACK, dlgb_back)

...
lret=modal(dlg_b)
...
call Dlguninit(dlg_b)
end Subroutine Dialog_b

SUBROUTINE dlgb_back( dlg, id, callbacktype )
!DEC$ ATTRIBUTES DEFAULT :: dlgb_back
use dflogm
implicit none
include 'resource.fd'
type (dialog):: dlg
integer:: id, callbacktype
if (callbacktype == dlg_clicked) then
CALL DlgUninit(dlg)
! Back to Dialog A
call dialog_A()
endif
END SUBROUTINE dlgb_back

My problem is: When I clicked the 'back' button in dialog B, dialog A displayed. Then,in dialog A, if I selected the case 5, the program could run between dialog A and B, but, once I clicked the other case (not 5), the wrong message appeared.

How to get rid of it?

Thanks in advance!

wen

4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Then,in dialog A, if I selected the case 5, the program could run between dialog A and B, but, once I clicked the other case (not 5), the wrong message appeared.

I'm not sure what do you mean in this sentence -- what's the "wrong message"? An error message?

I can see something fishy in your code, though. Consider the case when user clicks ID_B_BACK. In dlgb_back, you do a DlgUnInit(dlg), which is a no-no. Can't tell you offhand where it may crash, but it might be once it actually exits dlgb_back, since dlgb is destroyed, and DFLOGM tries to act on a dlgb which is destroyed (as a variable).

You should try to restructure your code:
1) Don't call DlgUnInit from callback. Use DlgExit(dlg, id)instead, and test whether return value from DlgModal(dlg_b) is ID_B_BACK. Then do the cleanup.
2) Don't to create a recursive set of calls. In the example, you call Dialog_A, which calls Dialog_B, which indirectly calls dlgb_back, which calls Dialog_A, which may call Dialog_B... Something will eventually crash in a DlgUnInit (since it is already UnInited) or a DlgInit(since it is Inited twice). I'd use something along these lines:

Subroutine Dialog_A
LOGICAL:: DoAgain
DoAgain=.TRUE.
DO WHILE(DoAgain)
  DlgInit(Dlg_a)
  iRet=DlgModal(Dlg_a)
  SELECT CASE(Choice)
  ...
  CASE(5)
     CALL Dialog_B(DoAgain)
  END SELECT
  CALL DlgUnInit(Dialog_B)
END DO
!==========================
SUBROUTINE Dialog_B(DoAgain)
LOGICAL, INTENT(OUT):: DoAgain
...
iRet = DlgModal(DlgB)
IF (iRet == ID_B_BACK) THEN
  DoAgain = .TRUE.  !A should reappear
ELSE IF...
  DoAgain = .FALSE. !in cases when back is not pressed
END IF
CALL DlgUnInit(DlgB)
END SUBROUTINE Dialog_B
!============================
SUBROUTINE DlgB_Back(Dlg, ID, iEvent)
CALL DlgExit(Dlg, ID)

Jugoslav

Jugoslav
www.xeffort.com

Thank you, Jugoslavdujic.

You are completely right. But I did not use
lret=dlgsetsub(dlg_b, ID_B_BACK, dlgb_back)

and did not need the subroutine Dlgb_back.

Wen

True -- I forgot that a push button closes the dialog by default.

Jugoslav
www.xeffort.com

Leave a Comment

Please sign in to add a comment. Not a member? Join today