Link to home
Start Free TrialLog in
Avatar of steenpat
steenpat

asked on

Main dialog, child dialog communication

I am finding myself in a situation where I have a main dialog with children dialogs , such as tabs pages etc, where there is some sort of variable in the main dialog in which the children dialogs need to have access to it (not just read from it but also modify it). So what I have done for now is declare it a static member variable and the children dialog classes are friend classes of the main dialog. I don't really think this is a good approach to design since the static member variables are now stuck in memory until the program terminates. Would it be better to use thread messages between the dialogs? Or what other approaches to this problem should I consider?
ASKER CERTIFIED SOLUTION
Avatar of Zoppo
Zoppo
Flag of Germany 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
Avatar of steenpat
steenpat

ASKER

do i have to declare the parentdlg with DECLARE_DYNAMIC? .. i did this, and the dialog is crashing
For this issue it shouldn't make a difference if the dialog is declared with DECLARE_DYNAMIC.

Where does it crash?
error C2039: 'classCParentDlg' : is not a member of 'CParentDlg'
(21) : see declaration of ''CParentDlg'
 : error C2065: 'classCParentDlg' : undeclared identifier

this is the error i get when i use this code
This happens if you have no appropriate IMPLEMENT_DYNAMIC or the arguments for IMPLEMENT_DYNAMIC are wrong ...
i am getting these compile errors without using implement dynamic..
From MSDN:
http://msdn.microsoft.com/en-us/library/cfy5wsfk(VS.80).aspx

The class specified in the class_name parameter must be derived from CObject and must use the DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC, the DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE, or the DECLARE_SERIAL and IMPLEMENT_SERIAL macros as explained in the article CObject Class: Deriving a Class from CObject.
when i use declare_dynamic and implement_dynamic there are no compile errors, but when the dialog opens it fails to display child dialogs, and crashes when i try to press next, back etc.
Did this work without problems as you tried it with static member? Where does it crash?

Maybe you call this from a dialog which is not a direct child of the parent dialog? In this case you'll have to find another way to access the parent dialog's members. I.e. you could pass a pointer to the parent dialog to all child dialogs at creation or something like this.
"Did this work without problems as you tried it with static member? Where does it crash?"
Yes it worked without problems.

"Maybe you call this from a dialog which is not a direct child of the parent dialog?"
I'm not sure what is meant by 'direct child'. All I did was use Create in the parent dialog to create the child dialogs with second parameter of 'this' implying that this child dialog uses the main dialog as parent.
Well, then I don't see why it's not working.

Can you put a breakpoint after the line:
> CParentDlg* pParent = STATIC_DOWNCAST( CParentDlg, pWnd );
and check in debugger if the pParent is valid (not NULL) and points to a CParentDialog?

Regards,

ZOPPO
>>>> All I did was use Create in the parent dialog to create the child dialogs with second parameter of 'this'

Where did you create the child dialogs? The earliest time you should do that is in MainDialog::OnInitDialog after the baseclass function CDialog::OnInitDialog already was called.

Did you initialize the member you added to your dialog in the constructor?

When did you access that member in your child dialogs? Note, the GetParent function works by means of the windows handle (m_hWnd). So, the child dialogs must have a valid window attached before you can call GetParent. So, you can't do it before the OnInitDialog of the child dialogs and I would suggest to do it after calling the CDialog::OnInitDialog just to make sure that the windows properly were initialized.
>>>> STATIC_DOWNCAST( CParentDlg, pWnd );
I would recommend against using that macro. Though it makes a runtime check regarding the MFC class hierarchie (if the DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC properly were defined)  it actually is less good and more error-prone than a C++ dynamic_cast which would check already at compile-time. So better do

   CParentDlg* pParent = dynamic_cast<CParentDlg*>(GetParent());

Again: don't forget that GetParent() couldn't be called before OnInitDialog.

If you need to access the parent's member before, you should store the parent's pointer in a member variable, which already was declared correctly as a CParentDlg* in the class header of the child dialogs.
   
I am setting break points on the main dialog's oninitdialog, .. none of them are being tripped even though the dialog launches. when i dont use declare_dynamic none of this crap occurs. is there something special that has to be done when using declare_dynamic
the children dialogs are not being created because theres a function in the main dialogs oninitdialog that creates them, oninitdialog is not ever being called when i declare it as dynamic.. i hate mfc
ok
.. i got some success doing this
IMPLEMENT_DYNAMIC(CMyclass, CDialog).. instead of IMPLEMENT_DYNAMIC(CMyclass, CWnd)
i dont understand why I had to implement it like this.. doesnt CDialog derivce from CWnd anyway,.. that makes no sense
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
yeah I never use the wizards. I am sure that is much faster, but i always end up doing it manually for one reason or another. i guess i'll give you guys half n half even tho its not much pts cause both of you are helpful. thanks.