Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1209
  • Last Modified:

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?
0
steenpat
Asked:
steenpat
  • 10
  • 5
  • 3
2 Solutions
 
ZoppoCommented:
Hi steenpat,

IMO you don't need to use static members. You can just use a normal member and access it via a pointer to the parent dialog, i.e.:

class CParentDlg ...
{
 public:
  int m_nMember;
 ...
};

void
CChildDlg::AnyFunction()
{
 CWnd* pWnd = GetParent();
 CParentDlg* pParent = STATIC_DOWNCAST( CParentDlg, pWnd );
 if ( NULL == pParent )
 {
  ASSERT( 0 );
  return;
 }
 pParent->m_nMember = 5;
}

BTW, it would be nicer to declare that member in CParentDlg as private and implement access to the member using getter/setter functions.

Hope that helps,

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

Where does it crash?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
steenpatAuthor Commented:
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
0
 
ZoppoCommented:
This happens if you have no appropriate IMPLEMENT_DYNAMIC or the arguments for IMPLEMENT_DYNAMIC are wrong ...
0
 
steenpatAuthor Commented:
i am getting these compile errors without using implement dynamic..
0
 
steenpatAuthor Commented:
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.
0
 
steenpatAuthor Commented:
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.
0
 
ZoppoCommented:
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.
0
 
steenpatAuthor Commented:
"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.
0
 
ZoppoCommented:
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
0
 
itsmeandnobodyelseCommented:
>>>> 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.
0
 
itsmeandnobodyelseCommented:
>>>> 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.
   
0
 
steenpatAuthor Commented:
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
0
 
steenpatAuthor Commented:
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
0
 
steenpatAuthor Commented:
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
0
 
itsmeandnobodyelseCommented:
>>>> oninitdialog is not ever being called when i declare it as dynamic.. i hate mfc
Actually, the DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC macros is essential for some MFC functionality. It rarely makes problems cause in almost all cases it was generated by the wizard. If you experience problems you most probably have done it manually and made some mistakes ...

Create a test dialog project from scratch using MFC wizard. Check the DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC macros in the dialog sources and place your own macros exactly at the same positions. Be aware that the IMPLEMENT_DYNAMIC macro has two arguments and make sure that you have used the parent dialog class (which is CDialog for all CDialog derived classes). In the class header be aware that after the DECLARE_DYNAMIC macro you should explicitly set the access specifier, e. g.  public:, cause the DECLARE_DYNAMIC changes that (I mean it is protected:). If using the IMPLEMENT_DYNAMIC you also *must* have a message map defined by (at least) a BEGIN_MESSAGE_MAP and a END_MESSAGE_MAP macro. Copy that from your wizard generated sample and exchange the names properly.
0
 
steenpatAuthor Commented:
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.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 10
  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now