How to pass TopWindow's public variable into child dialog? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 324
Joined: Mon Oct 06, 2008 12:55 pm

How to pass TopWindow's public variable into child dialog?

Post by samsam598 » Thu Aug 13, 2009 12:29 pm

Greetings to everybody!

I have thought the subjected is quite simple but I failed to make it.So I try to describe my question as this;
1. Main widget(Top Window): MyFrame

Code: Select all

class MyFrame:public wxFrame
{
    public:
    int choice;
    private:
    MyDialog* myDialog;
    ...
};
2.Child dialog MyDialog:

Code: Select all

class MyDialog:public wxDialog{...};
3. Click event of Open MenuItem in the menu of MyFrame:

Code: Select all

void MyFrame::OpenDialogClick(wxCommandEvent& event)
{
    myDialog=new MyDialog(this);
    myDialog->ShowModal();
    //do stuff
    delete myDialog;
}
4.Relative include head file has been included to ensure communicate between MyFrame & MyDialog .

Now I want to use variable choice in myDialog,how?
I tried this:

Code: Select all

void MyDialog::DoStuff()
{
    int theChoice;
    theChoice= (Myframe*)wxApp::GetTopWindow()->choice;//does not work,error msg see below;
    theChoice= (MyFrame*)this->GetParent()->choice;//does not work,error msg see below;
}
**Error message:
'class wxWindow' has no member named 'choice'

Any idea?
Thanks in advance.
Regards,
Sam
-------------------------------------------------------------------
Windows xp
VS.Net 2003/MinGW 3.4.5 C::B character set: UTF-8
wxWidgets github 3.0 RC1 Unicode Static build,Unicode Shared build.

swapd0
I live to help wx-kind
I live to help wx-kind
Posts: 169
Joined: Mon May 14, 2007 11:16 am
Location: Spain

Re: How to pass TopWindow's public variable into child dialo

Post by swapd0 » Thu Aug 13, 2009 12:37 pm

it's better like this:

Code: Select all

void MyFrame::OpenDialogClick(wxCommandEvent& event)
{
    MyDialog myDialog(this);
    if (myDialog.ShowModal()==wxID_OK)
    {
      DoStuff(myDialog.choice);
    }

}
some () missing, anyway remeber that mydialog is destroyed and in dostuff the choice will have garbage (in your solution)

Code: Select all

void MyDialog::DoStuff()
{
    int theChoice;
    theChoice= ((Myframe*)wxApp::GetTopWindow())->choice;//does not work,error msg see below;
    theChoice= ((MyFrame*)this)->GetParent()->choice;//does not work,error msg see below;
}
Last edited by swapd0 on Thu Aug 13, 2009 12:40 pm, edited 1 time in total.

ilovasz
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue Jul 10, 2007 6:56 pm

Post by ilovasz » Thu Aug 13, 2009 12:39 pm

Hi,

I usually use

Code: Select all

wxTheApp->GetTopWindow()
to get access to the main frame.

LI

samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 324
Joined: Mon Oct 06, 2008 12:55 pm

Post by samsam598 » Thu Aug 13, 2009 12:41 pm

Hi swapd0,

Thanks so much for your help.
I've tried both of the suggestion you mentioned,but it still does not work.

For this->GetParent() one,the error message is the same;
For wxApp->GetTopWindow() one,now the error message is as below:
cannot call member function `virtual wxWindow* wxAppBase::GetTopWindow() const' without object|

Clue?Many thanks.
Regards,
Sam
-------------------------------------------------------------------
Windows xp
VS.Net 2003/MinGW 3.4.5 C::B character set: UTF-8
wxWidgets github 3.0 RC1 Unicode Static build,Unicode Shared build.

swapd0
I live to help wx-kind
I live to help wx-kind
Posts: 169
Joined: Mon May 14, 2007 11:16 am
Location: Spain

Post by swapd0 » Thu Aug 13, 2009 12:52 pm

Why don't you pass the varible to the dialog constructor? IMHO it's not a clean solution to access a main window variable from a dialog. Pass it into the constructor or using a method, like setChoice or something

Code: Select all

    myDialog=new MyDialog(this, choice);
    myDialog->ShowModal();
    //do stuff
    delete myDialog;

samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 324
Joined: Mon Oct 06, 2008 12:55 pm

Post by samsam598 » Thu Aug 13, 2009 12:57 pm

swapd0 wrote:Why don't you pass the varible to the dialog constructor? IMHO it's not a clean solution to access a main window variable from a dialog. Pass it into the constructor or using a method, like setChoice or something

Code: Select all

    myDialog=new MyDialog(this, choice);
    myDialog->ShowModal();
    //do stuff
    delete myDialog;
Hi swapd0,

I got it.Yeah.. This works,quite easy and clean.:)

Hi ilovasz,

This one works:

Code: Select all

choice=((usesqliteAppFrame*)wxTheApp->GetTopWindow())->choice;
But why?Any difference?

Thank you both so much for all your help!
Last edited by samsam598 on Thu Aug 13, 2009 12:58 pm, edited 2 times in total.
Regards,
Sam
-------------------------------------------------------------------
Windows xp
VS.Net 2003/MinGW 3.4.5 C::B character set: UTF-8
wxWidgets github 3.0 RC1 Unicode Static build,Unicode Shared build.

Romas
I live to help wx-kind
I live to help wx-kind
Posts: 176
Joined: Mon Jun 16, 2008 11:07 am
Location: Kaunas

Post by Romas » Thu Aug 13, 2009 12:57 pm

Why are you doing this in hard way? You cannot get dialog as top window after showmodal, because that dialog is not shown. Why cannot you do stuff with the pointer to that dialog (right after showmodal and before delete dialog)?
Everything requires a line of code.

samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 324
Joined: Mon Oct 06, 2008 12:55 pm

Post by samsam598 » Thu Aug 13, 2009 1:01 pm

Romas wrote:Why are you doing this in hard way? You cannot get dialog as top window after showmodal, because that dialog is not shown. Why cannot you do stuff with the pointer to that dialog (right after showmodal and before delete dialog)?
Because my MyDialog::DoStuff is just a button click event.
Actual code:

Code: Select all

void MyDialog::OnBtnReadSQLiteDBClick(CommandEvent& event){}
Thank you for your help!
Regards,
Sam
-------------------------------------------------------------------
Windows xp
VS.Net 2003/MinGW 3.4.5 C::B character set: UTF-8
wxWidgets github 3.0 RC1 Unicode Static build,Unicode Shared build.

TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV » Thu Aug 13, 2009 6:38 pm

With

Code: Select all

void MyFrame::OpenDialogClick(wxCommandEvent& event) 
{ 
    MyDialog myDialog(this); 
    ...
}
it seems easy to retrieve a pointer to MyFrame into MyDialog (myDialog(this)). If MyFrame provides sufficient getters/setters, you can get/set any MyFrame' attributes from MyDialog.

Passing the value directly into MyDialog is also a nice way if you need only a few MyFrame's attributes.

The "((Myframe*)wxApp::GetTopWindow())->choice" way is a very ugly solution which makes use of framework specificites whereas C++ (and OOP in general) already provides all the necessary stuff !
Last edited by TrV on Thu Aug 13, 2009 6:42 pm, edited 1 time in total.

Estien77
Knows some wx things
Knows some wx things
Posts: 31
Joined: Tue Jan 13, 2009 8:38 pm
Location: Canada, eh?

Post by Estien77 » Thu Aug 13, 2009 6:38 pm

Code: Select all

choice=((usesqliteAppFrame*)wxTheApp->GetTopWindow())->choice;

Code: Select all

((MyFrame*)this)->GetParent()->choice;
The reason that the first one works is that you are casting the result of GetTopWindow to your frame class. The second should work if you move the ')' like this:

Code: Select all

((MyFrame*)this->GetParent())->choice;
if(work == fun)
{
pigsCanFly = true;
}

samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 324
Joined: Mon Oct 06, 2008 12:55 pm

Post by samsam598 » Fri Aug 14, 2009 12:44 am

TrV wrote:With

Code: Select all

void MyFrame::OpenDialogClick(wxCommandEvent& event) 
{ 
    MyDialog myDialog(this); 
    ...
}
it seems easy to retrieve a pointer to MyFrame into MyDialog (myDialog(this)). If MyFrame provides sufficient getters/setters, you can get/set any MyFrame' attributes from MyDialog.

Passing the value directly into MyDialog is also a nice way if you need only a few MyFrame's attributes.

The "((Myframe*)wxApp::GetTopWindow())->choice" way is a very ugly solution which makes use of framework specificites whereas C++ (and OOP in general) already provides all the necessary stuff !
Hi TrV,
I got your point but I am sorry I don't know exactly "how to use the pointer to MyFrame in MyDialog.Don't you mean this->GetParent()?If not,could you please post a piece of code?Thanks a lot.

To Estien77: the "this->GetParent()" one you mentioned works.Thanks. I was wondering why I did not try that cast last night,I remembed I have tried all the possible cast,maybe I was driven crazy at that moment...

To All have replied my question:
I think my orignial problem has been solved.All your answers are acceptable.But allow my delay a moment to wait whether TrV would like to figure me out his point as I still do not understand how to do.
Last edited by samsam598 on Fri Aug 14, 2009 1:13 am, edited 3 times in total.
Regards,
Sam
-------------------------------------------------------------------
Windows xp
VS.Net 2003/MinGW 3.4.5 C::B character set: UTF-8
wxWidgets github 3.0 RC1 Unicode Static build,Unicode Shared build.

TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV » Fri Aug 14, 2009 8:39 am

TrV wrote:With

Code: Select all

void MyFrame::OpenDialogClick(wxCommandEvent& event) 
{ 
    MyDialog myDialog(this); 
    ...
}
it seems easy to retrieve a pointer to MyFrame into MyDialog (myDialog(this)). If MyFrame provides sufficient getters/setters, you can get/set any MyFrame' attributes from MyDialog.
MyDialog.h

Code: Select all

...
class MyFrame; // declaration for cross-reference MyFrame <-> MyDialog
...
class MyDialog : wxDialog {
    public:
        MyDialog(wxWindow* parent);
        ...
    private:
        MyFrame* mainFrame; // pointer to MyFrame
        ...
}
MyDialog.cpp

Code: Select all

...
#include "MyFrame.h"

MyDialog::MyDialog(wxWindow* parent)
: wxDialog(parent, -1, "diag title")
, mainFrame((MyFrame*)parent) // inits a MyFrame pointer
{
    ...
}

void MyDialog::AnyMethod()
{
   ::wxMessageBox(mainFrame->GetAttribute()); // assuming GetAttribute() returns value of an attribute as a string
}

samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 324
Joined: Mon Oct 06, 2008 12:55 pm

Post by samsam598 » Fri Aug 14, 2009 9:07 am

Hi TrV,

Thank you so much .I Got it.

Regards,
Sam
Regards,
Sam
-------------------------------------------------------------------
Windows xp
VS.Net 2003/MinGW 3.4.5 C::B character set: UTF-8
wxWidgets github 3.0 RC1 Unicode Static build,Unicode Shared build.

Post Reply