Solved

C++, MFC: Supplying constructor arguments to a CDialog derived class correctly

Posted on 2007-11-20
17
2,199 Views
Last Modified: 2013-12-14
Hello,

I would like to supply a constructor argument to a wizard-generated CDialog derived class in MFC. This is the natural way to do it, because the dialog's content is predicated on a single seed value (an integer).

CMyDialog TheDialog(5); // TheDialog is instantiated

I see that wizard generated code for CDialog derived classed supplies a constructor like this:

CMyDialog ::CMyDialog (CWnd* pParent /*=NULL*/)
      : CDialog(CMyDialog ::IDD, pParent)
{

}

I would like to instantiate this variable as above, with a particular class member integer's value initiated as described.

This:


CMyDialog::CMyDialog (CWnd* pParent /*=NULL*/,int sku_is)
      : CDialog(CEditExistingProductDialog::IDD, pParent)

{
      sku = sku_is; // sku is the class member

}

causes an assertion failure when I supply CWnd* pParent as "this" (from anothe CDialog derived class), or if I supply NULL.

How should I go about getting this thing to work as described?

Regards,
Sternocera
0
Comment
Question by:sternocera
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 3
  • +6
17 Comments
 
LVL 40

Accepted Solution

by:
evilrix earned 168 total points
ID: 20321586
So, you added the new constructor param, it built ok but then after that you get the assertion? And if you revert the code I presume the assertion goes away?

Do you now have both constructors or just your new version?

BTW: Prefer to use constructor initialization lists -- they are more efficient...

CMyDialog::CMyDialog (CWnd* pParent /*=NULL*/,int sku_is)
      : CDialog(CEditExistingProductDialog::IDD, pParent), sku(sku_is)

{
}
0
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 166 total points
ID: 20321660
Will be less confusing if you have just one constructor like:

prototype:
      CMyDialog (int sku_is, CWnd* pParent =NULL);

implementation:
CMyDialog::CMyDialog (int sku_is, CWnd* pParent /*=NULL*/)
      : CDialog(CEditExistingProductDialog::IDD, pParent)

{
      sku = sku_is; // sku is the class member
}

notice the order in arguments in constructor
0
 
LVL 11

Expert Comment

by:DeepuAbrahamK
ID: 20321965

When you give defualt arguments, the default arguments should be placed in the right most parameter
Have a look at this:
http://web.mit.edu/merolish/ticpp/Chapter07.html
Best Regards,
DeepuAbrahamK
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Expert Comment

by:yuy2002
ID: 20325948
In header file, you should decalre CMyDialog construct fuction with the second parameter initialized.

class CMyDialog : public CDialog
{
// Construction
public:
      CMyDialog (CWnd* pParent = NULL,int sku_is = 0);      // standard constructor
...
}
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20326192
>> In header file, you should decalre CMyDialog construct fuction with the second parameter initialized.
Um, why? That is only useful if it valid to have sku_is with a default value of 0.
0
 

Author Comment

by:sternocera
ID: 20326813
Any variation on the default wizard generated constructor doesn't seem to do what's expected.

CMyDialog (int sku_is, CWnd* pParent =NULL);

doesn't work any better then:

CMyDialog (CWnd* pParent =NULL, int sku_is);

I've decided that it's more trouble then it's worth; I've just made the variable public and explicitly modified it before I call the dialog's DoModal().

Thanks.



0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20326848
>>>> causes an assertion failure when I supply CWnd* pParent as "this"
>>>>  (from anothe CDialog derived class), or if I supply NULL.

I would assume that you do more than

        sku = sku_is; // sku is the class member

in the constructor. Or you try to create the dialog in the constructor of the other dialog class. Break into the debugger and examine the call stack when the assertion comes. Most likely it says that the m_hWnd is invalid for your current dialog or the parent dialog. That is not astonishing if you have not created a window for the dialog until then. You can't use a dialog CWnd pointer prior to the WM_INIT_DIALOG message which was issued after CDialog::Create and was handled in CYourDialog::OnInitDialog.  

So, the normal thing is that you have some button in your first dialog. When it is clicked you will have a handler function like that:

void MyFirstDialog::OnBtnClickedStartSecondDialog()
{
       CMyDialog mydlg(this, 123);   // 123 is sku_is
       mydlg.DoModal();
}

Note, here you can use the 'this' as the first dialog already was created and has a valid windows handle. The DoModal will create your second dialog window and make a modal dialog.

Regards, Alex
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20326849
I tried doing this this morning without any problems. I'm wondering if the problem isn't actually this bit of code but somewhere else. Maybe, if it's not a big project, you could upload it to http://www.ee-stuff.com/ so we can have a look at it for you?
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20326872
Note, for any change you make you *have to* make a rebuild cause the 'precompiled header' must be recreated. In some versions of Visual Studio (or when working with a versioning system) the PCH was not automatically rebuilt waht may cause very strange errors and assertions (like the ones you posted).
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 20327439
IMHO the initial suggestion by Jaime is the way to achieve what you want and should work without any problems.

ps.
Make certain the original declaration isn't still there in the header and .cpp file :-
CMyDialog (CWnd* pParent /*=NULL*/)

otherwise you might actually be calling that somewhere instead of your customised one.
0
 

Author Comment

by:sternocera
ID: 20327459
interface arguments are consistent with implementation arguments, that's not it.

It seems counter-intuitive to me too, but it is so.


Thanks,
Sternocera
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20327609
Can you post the function where you were using the CMyDialog constructor? And where the assertion pops up? Can you post the current call stack then?
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 20327823
ps.

I hope you don't have code like this

CDlg1 dlg1;
dlg1.DoModal();

CDlg2 dlg2(42, &dlg1);   <<----  Assuming CDlg1 requires and int and a CWnd pointer in that order
At this point dlg1 as a WINDOW does not exist any more
0
 

Author Comment

by:sternocera
ID: 20327843
No, I appreciate that  CDlg1 would cease to exist,
Regards,
Sternocera
0
 
LVL 49

Assisted Solution

by:DanRollins
DanRollins earned 166 total points
ID: 20356425
I find it best to avoid tinkering with the wizard-generated ctors, especially in the case described because...

The normal way to "pass a value" into a CDialog-derive object is to provide a member variable and assign it a value before using DoModal() or Create().  E.g.:

CDlg1 dlg1;
dlg1.m_sku= 5;
dlg1.DoModal();

Then take action (that needs the m_sku value) in on the OnInitDialog()
0
 
LVL 1

Expert Comment

by:Computer101
ID: 21026318
Forced accept.

Computer101
EE Admin
0

Featured Post

Enroll in June's Course of the Month

June’s Course of the Month is now available! Experts Exchange’s Premium Members, Team Accounts, and Qualified Experts have access to a complimentary course each month as part of their membership—an extra way to sharpen your skills and increase training.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

696 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question