Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28455 Discussions

Exit a dialog box within a modeless dialog box

onkelhotte
New Contributor II
652 Views
Hi there,
I display a modeless dialog in my QuickWinApp. On this dialog I open a new dialog. When I exit this new dialog, my whole App closes.
Is there a way to close only the new dialog?
Thanks in advance,
Markus
0 Kudos
10 Replies
Jugoslav_Dujic
Valued Contributor II
652 Views
AFAIK that shouldn't happen.

Sanity check first: do you perhaps reuse the same Dlg variable for both dialogs? That could easily produce such effects.

Jugoslav
0 Kudos
onkelhotte
New Contributor II
652 Views
Code:
l = InsertMenuQQ(2,6,$MenuEnabled,'Display Dialog'C,DisplayDialog)
l = DlgInit(IDD_DIALOG_Main, dlgMain)
l = DlgSetSub(dlgMain,IDC_BUTTON_GPmod,OnButton)
.
.
subroutine DisplayDialog
l = DlgModeless(dlgMain)
.
.
subroutine OnButton (dlg,ibutton,itype)
select case (iButton)
  case (IDC_BUTTON_GPmod)
    call EditDialog
end select
.
.
subroutine EditDialog
l = DlgInit(IDD_DIALOG_InputGPulver,dlgInput)
l = DlgSetSub(dlgInput,IDOK,OnEditButton)
.
.
subroutine OnEditButton (dlg,ibutton,itype)
select case (iButton)
  case (IDOK)
    call DlgExit(dlgInput)
end select


I insert a new menu to start the main dialog dlgmain. This is necessary to interact with the dialog whilst the calculation (you gave me the hint a few weeks ago).
After that, the main dialog is initialized and started by clicking on the menu entry.
On the main dialog is a button IDC_BUTTON_GPmod that opens an input dialog dlginput.
When I exit the input dialog by clicking okay the whole app will be closed.
I tried to open the input dialog via dlgmodal, dlgmodelwithparent, dlgmodeless with SW_RESTORE with the same results.
MaybeI have to open the main dialog in a different way...
Markus
0 Kudos
Jugoslav_Dujic
Valued Contributor II
652 Views
It should work.

Try to insert IFLOGM.f90 from C:Program FilesIntelCompilerFortran9.0IA32Include into your project. First, verify that variables dlg and inputDlg within OnEditButton are the same ones (e.g. their LOC()s). Then, you can step into DlgExit of OnEditButton. However, source for DlgEndDialog is not available. What happens if you replace DlgExit with call DlgFlush(); DestroyWindow(dlg%hwnd)?

Also, please remind me why the dialog had to be modeless? Was it threading issue or something else?

Jugoslav
0 Kudos
anthonyrichards
New Contributor III
652 Views
If I were you, I would not use the default IDOK butuse my own 'OK' identifier, such as IDC_EDIT_OK. This will ensure a unique value for a button and avoid any possibility of it being acted upon by any other procedure. When you have given unique identifiers to all your buttons, try it again and see if the problem remains. I have written QuickWin programs that open dialogs and never observed what you have found (I use CVF 6.6). Good luck. (Also, stop the 'OK' button from being the default button...)
0 Kudos
Jugoslav_Dujic
Valued Contributor II
652 Views
I disagree; I prefer having IDOK as the identifier of OK throughout, as it's de facto standard. I see it as paired with IDCANCEL (=2), which even has a special status: closing a dialog via button sends a WM_COMMAND/IDCANCEL. I don't see how IDOK would interact with anything.

I'd guess that Onkel's application closes due to a I/O error or like rather than exiting cleanly through WM_QUIT arriving somehow into main message loop. I'd check that using Spy++.

Jugoslav
0 Kudos
onkelhotte
New Contributor II
652 Views
argh, you can beat me if you want...
calling a simple
do while( GetMessage (mesg, NULL, 0, 0) )
if ( DlgIsDlgMessage(mesg) .EQV. .FALSE. ) then
lret = TranslateMessage( mesg )
ret = DispatchMessage( mesg )
end if
end do
after you display the second dialog is very important whenusing a modeless dialog... So it is clear that the WM_DESTROY commandcloses the whole app. But thanks for your help.
Markus

Message Edited by OnkelHotte on 11-25-2005 02:43 AM

Message Edited by OnkelHotte on 11-25-2005 02:46 AM

0 Kudos
Jugoslav_Dujic
Valued Contributor II
652 Views
Hmmmm. I wouldn't agree with the diagnose. WM_DESTROY has hWnd as the argument and it will (should?) never end up in frame window procedure.

By adding the message loop you achieved in effect, (semi-)modal behavior.

Note: "modal dialogs" are modal in two ways: 1) they stop further execution of the code that invoked them and 2) they disable their parent window. They achieve 1) by executing a message loop, like you just did. They achieve 2) by calling EnableWindow(hwndParent, FALSE). Thus, you made it modal in sense 1), and you could achieve the same by calling DlgModal and EnableWindow(hwndParent, TRUE) somewhere from DlgInit.

(Also note that all of this is on per-thread basis, i.e. message loops from one thread don't affect anything in other threads).

The idea of "true" modeless dialogs is that they're pumped by an existing message loop, (in this case QuickWin's one, burried in qwin.lib). Unless that message loop does something dirty, I fail to see how WM_DESTROY for your dialog could possibly close the main window.

I don't see how you can cleanly exit your application now. As I expect, when you close the main window, its WM_DESTROY handler posts WM_QUIT to your message loop, which is exited, but WM_QUIT will never reach the original message loop. (Again, unless there's something like ExitProcess in the original WM_DESTROY handler).

I'll scrap up an example and try to check what's going on.

Jugoslav
0 Kudos
Jugoslav_Dujic
Valued Contributor II
652 Views
Here's a very simple sample which works quite fine without explicit message loops.

Note, however, SAVE attribute for TYPE(Dialog) variables. If your TYPE(Dialog) variables are local and without SAVE attribute, bad things may happen .

Jugoslav
0 Kudos
onkelhotte
New Contributor II
652 Views

Your example works fine and doesnt close the application...

My code did :-) And why? Maybe I should not delete so many lines when posting my source...

l = DlgInit(IDD_DIALOG_InputGPulver,dlgInput)
l = DlgSetSub(dlgInput,IDD_DIALOG_InputGPulver,EditInit)
call DlgModeless(dlgInput)

And when we look now what happens in subroutine EditInit:

if (callbacktype == dlg_init) then
...init something...
else if (callbacktype == dlg_destroy) then
call PostQuitMessage(0)
endif

The PostQuitMessage(0) works fine for the main dialog, but not in further dialogs... I should not copy & paste that much :-)

Thanks for your help and have a nice weekend!

Markus

0 Kudos
Jugoslav_Dujic
Valued Contributor II
652 Views
I should not copy & paste that much :-)

I'm half-seriously considering the idea of writing a clipboard monitor application/service to be installed on all computers on my colleagues (mine included). The application shoud:

- monitor all paste operations from the clipboard
- recognize if the clipboard contents are source code
- if it is, depending on configuration and code length, it will do one or more things:
* display annoying message box
* stop the paste operation
* (add other nasty things at will)

The point is to discourage "copy-paste programming" which is one of Sources of All Evils .

Now seriously, "riding" the modeless dialogs on QW message loop has the disadvantage that Tab, Esc and Enter keys are not handled correctly, because it doesn't call DlgIsDlgMessage. If you can live with it... The general workaround could be to write a message hook and call DlgIsDlgMessage from there. Less elegant one could be to resort to DIY message loops, provided that you solve quitting problems with correctly propagating WM_QUIT message all the way down.

Jugoslav
0 Kudos
Reply