[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

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

Posted on 2007-11-20
17
Medium Priority
?
2,331 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 672 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 664 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:Deepu Abraham
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
Independent Software Vendors: 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 45

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 45

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 664 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

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

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

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Suggested Courses

650 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