Link to home
Start Free TrialLog in
Avatar of sternocera
sternocera

asked on

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

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
ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

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
Avatar of yuy2002
yuy2002

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
...
}
>> 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.
Avatar of sternocera

ASKER

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.



>>>> 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
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?
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).
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.
interface arguments are consistent with implementation arguments, that's not it.

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


Thanks,
Sternocera
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?
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
No, I appreciate that  CDlg1 would cease to exist,
Regards,
Sternocera
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Forced accept.

Computer101
EE Admin