Solved

Main dialog, child dialog communication

Posted on 2008-10-27
18
1,141 Views
Last Modified: 2013-11-20
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
Comment
Question by:steenpat
  • 10
  • 5
  • 3
18 Comments
 
LVL 30

Accepted Solution

by:
Zoppo earned 250 total points
Comment Utility
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
 

Author Comment

by:steenpat
Comment Utility
do i have to declare the parentdlg with DECLARE_DYNAMIC? .. i did this, and the dialog is crashing
0
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
For this issue it shouldn't make a difference if the dialog is declared with DECLARE_DYNAMIC.

Where does it crash?
0
 

Author Comment

by:steenpat
Comment Utility
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
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
This happens if you have no appropriate IMPLEMENT_DYNAMIC or the arguments for IMPLEMENT_DYNAMIC are wrong ...
0
 

Author Comment

by:steenpat
Comment Utility
i am getting these compile errors without using implement dynamic..
0
 

Author Comment

by:steenpat
Comment Utility
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
 

Author Comment

by:steenpat
Comment Utility
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
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
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
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:steenpat
Comment Utility
"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
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
>>>> 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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
>>>> 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
 

Author Comment

by:steenpat
Comment Utility
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
 

Author Comment

by:steenpat
Comment Utility
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
 

Author Comment

by:steenpat
Comment Utility
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
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 250 total points
Comment Utility
>>>> 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
 

Author Comment

by:steenpat
Comment Utility
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

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
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 goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
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.

772 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now