Solved

Main dialog, child dialog communication

Posted on 2008-10-27
18
1,162 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 31

Accepted Solution

by:
Zoppo earned 250 total points
ID: 22812515
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
ID: 22813584
do i have to declare the parentdlg with DECLARE_DYNAMIC? .. i did this, and the dialog is crashing
0
 
LVL 31

Expert Comment

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

Where does it crash?
0
Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

 

Author Comment

by:steenpat
ID: 22813754
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 31

Expert Comment

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

Author Comment

by:steenpat
ID: 22813845
i am getting these compile errors without using implement dynamic..
0
 

Author Comment

by:steenpat
ID: 22813895
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
ID: 22813901
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 31

Expert Comment

by:Zoppo
ID: 22813990
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
 

Author Comment

by:steenpat
ID: 22814053
"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 31

Expert Comment

by:Zoppo
ID: 22814154
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
ID: 22815790
>>>> 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
ID: 22815901
>>>> 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
ID: 22816050
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
ID: 22816072
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
ID: 22816115
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
ID: 22816193
>>>> 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
ID: 22816230
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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
twoTwo  challenge 35 108
mapAB Challlenge 35 160
Can not remove SSL certificate on iPhone 6 - iOS10.2 12 882
boost::uuid crashes 17 13
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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 concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

821 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