?
Solved

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

Posted on 2007-11-20
17
Medium Priority
?
2,260 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: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
Get MongoDB database support online, now!

At Percona’s web store you can order your MongoDB database support needs in minutes. No hassles, no fuss, just pick and click. Pay online with a credit card. Handle your MongoDB database support now!

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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

777 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