Re: How to modalize a dialog?
On 5 Nov., 21:50, Joseph M. Newcomer <newco...@flounder.com> wrote:
See below...
On Wed, 5 Nov 2008 12:35:44 -0800 (PST), ".rhavin grobert" <cl...@yahoo.d=
e> wrote:
Guess we have a modeless dialog (*pDlg) that is already created and
shown. i now want to provide a way to make it modal, eg, call a fn
that returns only after the dialog was EndDialog'ed. Return value is
not the point here, that is handled by some overloads. The following
snipped should "modalize" a dialog that is already created and shown
and is a copy from the CDialog::DoModal() source. But the call into
RunModalLoop() "locks" everything. Does someone know how to correctly
make an alredy created and shown dialog modal?
****
There are several different questions here.
For example, you CANNOT make a "modeless" dialog "modal" in the sense tha=
t it is
terminated by EndDialog. You CAN make it "modal" in that the parent is=
disabled until the
dialog terminates, which is a different question. Just call
GetParent()->EnableWIndow(FALSE); and you're done. Make sure that as p=
art of the
OnDestroy handler you re-enable the parent window.
You must make sure that EndDialog is never, ever, called for a modeless d=
ialog. This
means that you have to override OnCancel and OnOK and not call the superc=
lass, but instead
implement DestroyWindow to kill the dialog. You would notify the owner=
of the dialog by
using SendMessage or PostMessage that the dialog has closed, and include =
as WPARAM or
LPARAM the IDOK/IDCANCEL. I would NOT attempt at all the solution you =
have tried; it
looks like a recipe for disaster.
In MyDialog, EndDialog(), OnCancel(), Create(), OnOk() and DoModal()
will all be overloaded, so the dialog "knows" if it is created modal
or modeless. The point is: In a modal dialog scenario, you can do
something like this:
void CMyClass::DoSomethingFunny()
{
CMyDialog dlg;
ThisFnIsCalledBeforeDialog();
dlg.DoModal();
ProcessingContinuesHereAfterDialogEnded();
}
what im trying to acomplish is something similar for already existent
dialogs (modeless)
void CMyClass::DoSomethingQuiteMoreFunny(CMyDialog* dlg)
{
ThisFnIsCalledBeforeDialog();
pDlg->Modalize();
ProcessingContinuesHereAfterDialogEnded();
}
Note that "Ended" doesnt neccesarily mean that is has to be destroyed.
A modeless dialog is inherently asynchronous; you have made the common mi=
stake of thinking
you can impose synchronous behavior on an asyncrhonous mechanism. Don't w=
aste time trying.
I didnt understand everything, but the mfc-sources for Create() and
DoModal() seem to do much the same. whats the difference? they dont
seem to run in a different thread.
Since the only purpose of a modal dialog is to disable the main window wh=
ile the dialog is
active, that's trivial; and there is no reason to ever think that it make=
s sense to impose
synchronous behavior on asynchronous mechanisms; that's always a losing g=
ame. You started
out asking the wrong question; the right question is "I want the dialog t=
o have the
illusion of modality at some point", and confused that with an implementa=
tion that
approaches the problem from the wrong direction. The illusion of modal=
ity is simple:
disable the parent window. The notification of completion is asynchrono=
us.
Instead of writing
A();
dlg->Modalize();
B();
you should write
A();
Modalize();
LRESULT CMyWhatever::OnDialogFinished(WPARAM wParam, LPARAM)
{
if(wParam == IDOK)
...
dlg->Demodalize();
return 0;
}
where "Modalize" is now
void CMyDialog::Modalize()
{
GetParent()->EnableWIndow(FALSE);
}
and Demodalize re-enables the window.
Note that this solution is very easy to implement.
=
joe
yes, but not exactly what i want ;-)