Discussion:
OnInitDialog not getting called because of DoModal
(too old to reply)
Abubakar
2007-03-27 08:16:30 UTC
Permalink
Hi,

I'm creating/showing-up a new dialog box in a vc++ 2k5 mfc application. If I
show my dialog using a DoModal():

FeedBackDlg feedback (IDD_FEEDBACKDLG);
INT_PTR ret = feedback.DoModal();

the OnInitDialog method of my dialog doest not get called. But on the other
hand if I creat my dialog using:

FeedBackDlg *one = new FeedBackDlg();
one->Create(IDD_FEEDBACKDLG, NULL);
one->ShowWindow(SW_NORMAL);
one->UpdateWindow();

the OnInitDialog method gets called. What can I do so that the OnInitDialog
method gets when I'm showing the dialog through domodal()?

Regards,

..ab
David Lowndes
2007-03-27 10:37:59 UTC
Permalink
Post by Abubakar
I'm creating/showing-up a new dialog box in a vc++ 2k5 mfc application. If I
FeedBackDlg feedback (IDD_FEEDBACKDLG);
INT_PTR ret = feedback.DoModal();
the OnInitDialog method of my dialog doest not get called. But on the other
FeedBackDlg *one = new FeedBackDlg();
one->Create(IDD_FEEDBACKDLG, NULL);
one->ShowWindow(SW_NORMAL);
one->UpdateWindow();
the OnInitDialog method gets called.
The behaviour you say you're experiencing is not normal, you should
get the WM_INITDIALOG message regardless of how its created.

Can you temporarily remove all your code from the dialog except for
the WM_INITDIALOG handler and check if you then get it?

Dave
Abubakar
2007-03-27 10:30:38 UTC
Permalink
Post by David Lowndes
Can you temporarily remove all your code from the dialog except for
the WM_INITDIALOG handler and check if you then get it?
I dont have a handler for WM_INITDIALOG. I have only overrided the
OnInitDialog base class method. Do I need to map the WM_INITDIALOG to some
function myself?

..ab
Post by David Lowndes
Post by Abubakar
I'm creating/showing-up a new dialog box in a vc++ 2k5 mfc application. If I
FeedBackDlg feedback (IDD_FEEDBACKDLG);
INT_PTR ret = feedback.DoModal();
the OnInitDialog method of my dialog doest not get called. But on the other
FeedBackDlg *one = new FeedBackDlg();
one->Create(IDD_FEEDBACKDLG, NULL);
one->ShowWindow(SW_NORMAL);
one->UpdateWindow();
the OnInitDialog method gets called.
The behaviour you say you're experiencing is not normal, you should
get the WM_INITDIALOG message regardless of how its created.
Can you temporarily remove all your code from the dialog except for
the WM_INITDIALOG handler and check if you then get it?
Dave
David Lowndes
2007-03-27 11:38:56 UTC
Permalink
Post by Abubakar
Post by David Lowndes
Can you temporarily remove all your code from the dialog except for
the WM_INITDIALOG handler and check if you then get it?
I dont have a handler for WM_INITDIALOG. I have only overrided the
OnInitDialog base class method. Do I need to map the WM_INITDIALOG to some
function myself?
Sorry if I confused you there - it's the same thing, the message map
entry is provided by MFC behind the scenes. If you get to OnInitDialog
in one case you should get it in both!

Dave
Abubakar
2007-03-27 11:31:43 UTC
Permalink
When I added the Dialog as a new resource, I added the class to it that
inherited from CDialog (through the wizard) which automatically generated
some code for me. But strangely there was no code generated for OnInitDialog
method which usually is generated if you create a new mfc dialog based
application. So what I did is I wrote the declaration there myself in the
header file and wrote the definition to it in the cpp file. Since then I
noted that when I do a DoModal the execution doesnt get to the
OnInitDialog(), but if I use the ShowWindow() the execution does get to the
OnInitDialog().

..ab
Post by David Lowndes
Post by Abubakar
Post by David Lowndes
Can you temporarily remove all your code from the dialog except for
the WM_INITDIALOG handler and check if you then get it?
I dont have a handler for WM_INITDIALOG. I have only overrided the
OnInitDialog base class method. Do I need to map the WM_INITDIALOG to some
function myself?
Sorry if I confused you there - it's the same thing, the message map
entry is provided by MFC behind the scenes. If you get to OnInitDialog
in one case you should get it in both!
Dave
David Lowndes
2007-03-27 14:14:03 UTC
Permalink
Post by Abubakar
When I added the Dialog as a new resource, I added the class to it that
inherited from CDialog (through the wizard) which automatically generated
some code for me. But strangely there was no code generated for OnInitDialog
method which usually is generated if you create a new mfc dialog based
application. So what I did is I wrote the declaration there myself in the
header file and wrote the definition to it in the cpp file. Since then I
noted that when I do a DoModal the execution doesnt get to the
OnInitDialog(), but if I use the ShowWindow() the execution does get to the
OnInitDialog().
It should be the Create and DoModal operations that cause OnInitDialog
- not ShowWindow. You might want to clarify that first.

I've no idea why it isn't happening for you in the modal case - it
should be.

Dave
Joseph M. Newcomer
2007-03-27 15:59:00 UTC
Permalink
YOu got it wrong.

When you create a dialog (not a dialog-based app), you must add an OnInitDialog handler
using the classwizard (well, the properties sheet). Its declaration must be
virtual BOOL OnInitDialog();
if you just added a non-virtual method, it won't get called. If you added something that
has a message-map entry for WM_INITDIALOG, it won't get called.

Don't do things by hand when there are tools that do it for you, unless you really know
what you are doing.
joe
Post by Abubakar
When I added the Dialog as a new resource, I added the class to it that
inherited from CDialog (through the wizard) which automatically generated
some code for me. But strangely there was no code generated for OnInitDialog
method which usually is generated if you create a new mfc dialog based
application. So what I did is I wrote the declaration there myself in the
header file and wrote the definition to it in the cpp file. Since then I
noted that when I do a DoModal the execution doesnt get to the
OnInitDialog(), but if I use the ShowWindow() the execution does get to the
OnInitDialog().
..ab
Post by David Lowndes
Post by Abubakar
Post by David Lowndes
Can you temporarily remove all your code from the dialog except for
the WM_INITDIALOG handler and check if you then get it?
I dont have a handler for WM_INITDIALOG. I have only overrided the
OnInitDialog base class method. Do I need to map the WM_INITDIALOG to some
function myself?
Sorry if I confused you there - it's the same thing, the message map
entry is provided by MFC behind the scenes. If you get to OnInitDialog
in one case you should get it in both!
Dave
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
AliR (VC++ MVP)
2007-03-27 16:51:11 UTC
Permalink
"Joseph M. Newcomer" <***@flounder.com> wrote in message news:***@4ax.com...
..........
Post by Joseph M. Newcomer
if you just added a non-virtual method, it won't get called. If you added something that
has a message-map entry for WM_INITDIALOG, it won't get called.
Whether he declares the OnInitDialog as virtual in his class or not
shouldn't make any difference. It is declared as virtual in CDialog and
therefore will be virtual for any child class (as long as it has the same
signature).

BOOL OnInitDialog();

AliR.
Doug Harrison [MVP]
2007-03-27 17:03:43 UTC
Permalink
On Tue, 27 Mar 2007 10:59:00 -0500, Joseph M. Newcomer
Post by Joseph M. Newcomer
YOu got it wrong.
When you create a dialog (not a dialog-based app), you must add an OnInitDialog handler
using the classwizard (well, the properties sheet). Its declaration must be
virtual BOOL OnInitDialog();
if you just added a non-virtual method, it won't get called.
Using the virtual keyword in derived classes is optional. This is a
double-sided weakness of C++:

1. When you add a member function to a derived class, you must look at all
the base classes to ensure you don't override a virtual function.

2. When you add a virtual function to a base class, you must look at all
the existing derived classes to make sure you don't cause one of their
member functions to override the one you just defined.

Overriding and accessibility are orthogonal; that is, a derived class
doesn't require access to a virtual function in order to override it. This
is a bit of a mess, and C# definitely learned some lessons from it.
Post by Joseph M. Newcomer
If you added something that
has a message-map entry for WM_INITDIALOG, it won't get called.
Actually, that's a no harm, no foul practice. It's just redundant since
WM_INITDIALOG is one of the few messages whose handler is virtual.
Post by Joseph M. Newcomer
Don't do things by hand when there are tools that do it for you, unless you really know
what you are doing.
Agreed!
--
Doug Harrison
Visual C++ MVP
Alexander Grigoriev
2007-03-27 18:50:09 UTC
Permalink
Post by Doug Harrison [MVP]
On Tue, 27 Mar 2007 10:59:00 -0500, Joseph M. Newcomer
Using the virtual keyword in derived classes is optional. This is a
1. When you add a member function to a derived class, you must look at all
the base classes to ensure you don't override a virtual function.
2. When you add a virtual function to a base class, you must look at all
the existing derived classes to make sure you don't cause one of their
member functions to override the one you just defined.
I think it would be nice if VC issued a warning when 'virtual' inherited
(level 4) or 'virtual' overrides non-virtual (level 1). Who will submit a
feature suggection?
Abubakar
2007-03-29 11:55:26 UTC
Permalink
It is declared as virtual.

..ab
Post by Joseph M. Newcomer
YOu got it wrong.
When you create a dialog (not a dialog-based app), you must add an OnInitDialog handler
using the classwizard (well, the properties sheet). Its declaration must be
virtual BOOL OnInitDialog();
if you just added a non-virtual method, it won't get called. If you added something that
has a message-map entry for WM_INITDIALOG, it won't get called.
Don't do things by hand when there are tools that do it for you, unless you really know
what you are doing.
joe
Post by Abubakar
When I added the Dialog as a new resource, I added the class to it that
inherited from CDialog (through the wizard) which automatically generated
some code for me. But strangely there was no code generated for OnInitDialog
method which usually is generated if you create a new mfc dialog based
application. So what I did is I wrote the declaration there myself in the
header file and wrote the definition to it in the cpp file. Since then I
noted that when I do a DoModal the execution doesnt get to the
OnInitDialog(), but if I use the ShowWindow() the execution does get to the
OnInitDialog().
..ab
Post by David Lowndes
Post by Abubakar
Post by David Lowndes
Can you temporarily remove all your code from the dialog except for
the WM_INITDIALOG handler and check if you then get it?
I dont have a handler for WM_INITDIALOG. I have only overrided the
OnInitDialog base class method. Do I need to map the WM_INITDIALOG to some
function myself?
Sorry if I confused you there - it's the same thing, the message map
entry is provided by MFC behind the scenes. If you get to OnInitDialog
in one case you should get it in both!
Dave
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Doug Harrison [MVP]
2007-03-29 16:29:38 UTC
Permalink
Post by Abubakar
It is declared as virtual.
Again, it doesn't matter. What does matter is that it overrides the base
class version, which requires the signatures to match.
--
Doug Harrison
Visual C++ MVP
David Ching
2007-03-29 17:27:23 UTC
Permalink
Post by Doug Harrison [MVP]
Post by Abubakar
It is declared as virtual.
Again, it doesn't matter. What does matter is that it overrides the base
class version, which requires the signatures to match.
Yes, but also: it is important he override the virtual
CDialog::OnInitDialog() METHOD, and not handle the WM_INIT_DIALOG message
with an OnInitDialog() message handler. I've never understood why there are
both options, and from this discussion, only one is actually invoked.

-- David
Doug Harrison [MVP]
2007-03-29 19:20:26 UTC
Permalink
Post by David Ching
Yes, but also: it is important he override the virtual
CDialog::OnInitDialog() METHOD, and not handle the WM_INIT_DIALOG message
with an OnInitDialog() message handler. I've never understood why there are
both options, and from this discussion, only one is actually invoked.
If the WM_INITDIALOG handler is declared with the same signature as
CDialog::OnInitDialog, it'll override it and work fine. The WM_INITDIALOG
handler is one of a handful of message handlers implemented as a virtual
function. I've never investigated why it rates the special treatment, but
if you're really interested, I'm sure you could figure it out from the
source code.
--
Doug Harrison
Visual C++ MVP
David Ching
2007-03-30 02:55:12 UTC
Permalink
Post by Doug Harrison [MVP]
I've never investigated why it rates the special treatment, but
if you're really interested, I'm sure you could figure it out from the
source code.
Actually, I'm not! :-)

VC2005 seems to have removed the possibility of overriding the virtual
OnInitDialog(), but I could have sworn previous IDE's allowed you to both
override it and in addition, create a handler for WM_INITDIALOG. This was
the confusing part for me. I don't know if creating a handler for
WM_INITDIALOG generated the same signature as the virtual override or not.
But I do remember that I was confused that OnInitDialog (however I had
defined it) was not being called.

-- David
David Wilkinson
2007-03-30 09:24:01 UTC
Permalink
Post by David Ching
VC2005 seems to have removed the possibility of overriding the virtual
OnInitDialog(), but I could have sworn previous IDE's allowed you to both
override it and in addition, create a handler for WM_INITDIALOG. This was
the confusing part for me. I don't know if creating a handler for
WM_INITDIALOG generated the same signature as the virtual override or not.
But I do remember that I was confused that OnInitDialog (however I had
defined it) was not being called.
David:

In VC6, you use class wizard to add a handler for WM_INITDIALOG, but
what is actually added to the code is an override of the virtual funtion
OnInitDialog().

In the .h file the entry is added to the AFX_MSG section and appears as

virtual BOOL OnInitDialog();

(no afx_msg). No entry is placed in the MESSAGE_MAP section in the .cpp
file.

OnOk() and OnCancel() work the same way.

David Wilkinson
David Ching
2007-03-30 14:59:51 UTC
Permalink
In VC6, you use class wizard to add a handler for WM_INITDIALOG, but what
is actually added to the code is an override of the virtual funtion
OnInitDialog().
Thanks, I hadn't realized that. In one of the IDE's (maybe it was VC6), it
was also possible to add an override, not by adding a handler for the
WM_INITDIALOG message, but by going to another part of the wizard and
overriding the virtual function itself. This was what was confusing to me;
which one was I supposed to do? But if the same thing happened regardless,
I guess it didn't matter. I still remember that OnInitDialog() was not
being called for some reason, but the last project I tried, it worked fine.
I don't know what changed, or if I did something wrong in the first case.

Thanks,
David
Joseph M. Newcomer
2007-03-30 16:35:42 UTC
Permalink
Actually, in previous IDEs, if you tried to an a WM_INITDIALOG handler, it inserted the
virtual method. So if you REALLY wanted to handle the method, you had to manually add the
handler. I saw people doing that because they would say "I know I want the message and I
don't understand those virtual things". I had to repair the code, because I did silly
things like assume that DoDataExchange would work right, and when I used ClassWizard to
bind the controls to variables they didn't bind.
joe
Post by David Ching
Post by Doug Harrison [MVP]
I've never investigated why it rates the special treatment, but
if you're really interested, I'm sure you could figure it out from the
source code.
Actually, I'm not! :-)
VC2005 seems to have removed the possibility of overriding the virtual
OnInitDialog(), but I could have sworn previous IDE's allowed you to both
override it and in addition, create a handler for WM_INITDIALOG. This was
the confusing part for me. I don't know if creating a handler for
WM_INITDIALOG generated the same signature as the virtual override or not.
But I do remember that I was confused that OnInitDialog (however I had
defined it) was not being called.
-- David
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Joseph M. Newcomer
2007-03-27 15:56:24 UTC
Permalink
THere's something wrong with your declaration. What is the IDD_FEEDBACKDLG value doing
there?

WHy are you using new at all?

FeedBackDlg feedback;
INT_PTR ret = feedback.DoModal();

should be sufficient. I suspect you are invoking the wrong constructor due to your coding
error. By using 'new' you avoid this coding error, but you could avoid it just by not
including the IDD_FEEDBACKDLG in the first case.

I'm running dialogs in VS2005 without any problem, but I never used the erroneous form of
the constructor.
joe
Post by Abubakar
Hi,
I'm creating/showing-up a new dialog box in a vc++ 2k5 mfc application. If I
FeedBackDlg feedback (IDD_FEEDBACKDLG);
INT_PTR ret = feedback.DoModal();
the OnInitDialog method of my dialog doest not get called. But on the other
FeedBackDlg *one = new FeedBackDlg();
one->Create(IDD_FEEDBACKDLG, NULL);
one->ShowWindow(SW_NORMAL);
one->UpdateWindow();
the OnInitDialog method gets called. What can I do so that the OnInitDialog
method gets when I'm showing the dialog through domodal()?
Regards,
..ab
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Tom Serface
2007-03-27 16:05:13 UTC
Permalink
Hi Joe,

I'm saving this quote :o) Proof that, at least, something works!

Tom
Post by Joseph M. Newcomer
I'm running dialogs in VS2005 without any problem, but I never used the erroneous form of
the constructor.
joe
Joseph M. Newcomer
2007-03-28 05:55:17 UTC
Permalink
Of course, I only get one or two tests of the dialog before VS2005 crashes for
indeterminate reasons and has to be restarted....but the dialogs work.

There are actually a few things that work in VS2005, but they're hard to find.
joe
Post by Tom Serface
Hi Joe,
I'm saving this quote :o) Proof that, at least, something works!
Tom
Post by Joseph M. Newcomer
I'm running dialogs in VS2005 without any problem, but I never used the erroneous form of
the constructor.
joe
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Abubakar
2007-03-29 12:52:47 UTC
Permalink
Hey thanks, your code works just fine! The example I gave was taken from
msdn:
ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vclib/html/da4e2889-2903-4971-b086-86f9a2a3d965.htm

So I used the resource id of the dialog I wanted to show up but as it turned
out that it works without the resource id as in your code.

Regards,

..ab
Post by Joseph M. Newcomer
THere's something wrong with your declaration. What is the
IDD_FEEDBACKDLG value doing
there?
WHy are you using new at all?
FeedBackDlg feedback;
INT_PTR ret = feedback.DoModal();
should be sufficient. I suspect you are invoking the wrong constructor due to your coding
error. By using 'new' you avoid this coding error, but you could avoid it just by not
including the IDD_FEEDBACKDLG in the first case.
I'm running dialogs in VS2005 without any problem, but I never used the erroneous form of
the constructor.
joe
Post by Abubakar
Hi,
I'm creating/showing-up a new dialog box in a vc++ 2k5 mfc application. If I
FeedBackDlg feedback (IDD_FEEDBACKDLG);
INT_PTR ret = feedback.DoModal();
the OnInitDialog method of my dialog doest not get called. But on the other
FeedBackDlg *one = new FeedBackDlg();
one->Create(IDD_FEEDBACKDLG, NULL);
one->ShowWindow(SW_NORMAL);
one->UpdateWindow();
the OnInitDialog method gets called. What can I do so that the
OnInitDialog
method gets when I'm showing the dialog through domodal()?
Regards,
..ab
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Loading...