How do I return Parent that is top level window? 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
RealityMage
Experienced Solver
Experienced Solver
Posts: 75
Joined: Tue Aug 23, 2005 3:47 am

How do I return Parent that is top level window?

Post by RealityMage » Sun Apr 02, 2006 11:52 pm

Say I have a control which is a great-grandchild or something of a wxFrame. If I call "GetParent()" on that control, I get its immediate parent, which is not the wxFrame.

How can I get the Parent which is a top-level window of an arbitrary control?

cpp
I live to help wx-kind
I live to help wx-kind
Posts: 195
Joined: Wed Sep 28, 2005 9:42 pm

Post by cpp » Mon Apr 03, 2006 12:54 am

mhh, i dont think there is a wxXxx function to do it, but i think you can do it yourself, for a quick & dirty example:

Code: Select all

wxWindow* GetTopParent(wxWindow* pWindow)
{
    wxWindow* pWin = pWindow;
    while(true)
    {
        if(pWin->GetParent())
            pWin = pWin->GetParent();
        else
            break;
    }
    return pWin;
}
HTH
Hier Kommt die Sonne...

Thelvyn
Earned a small fee
Earned a small fee
Posts: 23
Joined: Sun Feb 26, 2006 8:03 pm
Location: Linwood Pa USA
Contact:

Post by Thelvyn » Tue Apr 04, 2006 7:56 am

I believe this does what you want actually.

wxWindow * wxApp::GetTopWindow()

Returns a pointer to the top window.
If the top window hasn't been set using wxApp::SetTopWindow, this function will find the first top-level window (frame or dialog) and return that.

or you could try this

wxWindow* wxWindow::GetGrandParent()

Returns the grandparent of a window, or NULL if there isn't one.

cpp
I live to help wx-kind
I live to help wx-kind
Posts: 195
Joined: Wed Sep 28, 2005 9:42 pm

Post by cpp » Tue Apr 04, 2006 9:23 pm

wxApp::GetTopWindow() returns the top window for the application, it doesnt necerarily mean that it will be the top parent of the requested control,
And wxWindow::GetGrandParent() is a just the same as calling GetParent()->GetParent(), so if the control whos parent you want is "deeper" than 2 parents, it wont work either. :wink:
Hier Kommt die Sonne...

Thelvyn
Earned a small fee
Earned a small fee
Posts: 23
Joined: Sun Feb 26, 2006 8:03 pm
Location: Linwood Pa USA
Contact:

Post by Thelvyn » Wed Apr 05, 2006 4:42 am

I do believe your solution ends up doing the same thing just in a more convuluted way.
If he wants to find a specific window thats a different story.

Code: Select all

wxFrame* GetParentFrame(wxWindow* pWindow)
{
    wxWindow* pWin = pWindow;
    wxFrame* pFrame = NULL;
    while( NULL == pFrame )  {
        pFrame = dynamic_cast<wxFrame*>( pWin );
        pWin = pWin->GetParent();
        if( NULL == pWin ) {
            break;
        }
    }
    return pFrame;
}

Jamie
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 205
Joined: Wed Mar 30, 2005 10:56 pm

Post by Jamie » Wed Apr 05, 2006 6:08 am

cpp wrote:

Code: Select all

wxWindow* GetTopParent(wxWindow* pWindow)
{
    wxWindow* pWin = pWindow;
    while(true)
    {
        if(pWin->GetParent())
            pWin = pWin->GetParent();
        else
            break;
    }
    return pWin;
}
But what if the control is a child of a dialog (which is top level) which itself is a child of a frame? Your solution would return the frame and not the top-level parent (the dialog).

Use ::wxGetTopLevelParent

cpp
I live to help wx-kind
I live to help wx-kind
Posts: 195
Joined: Wed Sep 28, 2005 9:42 pm

Post by cpp » Wed Apr 05, 2006 6:11 am

I do believe your solution ends up doing the same thing just in a more convuluted way.
nope, if for example the control whos parent he wants to find, is a child of a dialog or frame he created without a parent (another "top level" window), the solution i proposed would return that panel or dialog, not the same as wxApp::GetTopWindow()
Hier Kommt die Sonne...

cpp
I live to help wx-kind
I live to help wx-kind
Posts: 195
Joined: Wed Sep 28, 2005 9:42 pm

Post by cpp » Wed Apr 05, 2006 6:17 am

But what if the control is a child of a dialog (which is top level) which itself is a child of a frame? Your solution would return the frame and not the top-level parent (the dialog).
Yep, i guess your right about that, if he wants to limit the "parenthood" to windows wich are usually top level windows, then like you said ::wxGetTopLevelParent is the way to go. I assumed he wanted the "absolute" or "real" top level parent
Hier Kommt die Sonne...

Thelvyn
Earned a small fee
Earned a small fee
Posts: 23
Joined: Sun Feb 26, 2006 8:03 pm
Location: Linwood Pa USA
Contact:

Post by Thelvyn » Wed Apr 05, 2006 2:14 pm

I merely used the frame as an example of finding a specific window type from a nested class.

Could just as easily find a wxDialog based class in the same manner.
And how often do you create a dialog without a parent unless its the top level window to start with ? Thats not good practice in general.

Code: Select all


wxDialog* GetParentDialog(wxWindow* pWindow)
{
    wxWindow* pWin = pWindow;
    wxDialog* pDialog = NULL;
    while( NULL == pDialog )  {
        pDialog = dynamic_cast<wxDialog*>( pWin );
        pWin = pWin->GetParent();
        if( NULL == pWin ) {
            break;
        }
    }
    return pDialog;
}
Of course there is another solution entirely which is not the OOP way but works. Now the purist's will have a screaming fit over this idea but I am a pragmatist.
Just do what works.

Make a global pointer to the class he wants the pointer to and reference it that way. No searching required.

User avatar
ultim8
Knows some wx things
Knows some wx things
Posts: 28
Joined: Fri Dec 16, 2005 4:24 pm
Location: Burlington, VT

Post by ultim8 » Thu Jun 01, 2006 2:25 pm

cpp wrote:mhh, i dont think there is a wxXxx function to do it, but i think you can do it yourself, for a quick & dirty example:

Code: Select all

wxWindow* GetTopParent(wxWindow* pWindow)
{
    wxWindow* pWin = pWindow;
    while(true)
    {
        if(pWin->GetParent())
            pWin = pWin->GetParent();
        else
            break;
    }
    return pWin;
}
HTH
Not to split hair's, but I'm all about efficiency. This function will do the same thing without the nastyness of a infinite while loop and break:

Code: Select all

wxWindow *GetTopParent(wxWindow* pWindow)
{
	wxWindow* pWin = pWindow;

	while(pWin->GetParent())
    		pWin = pWin->GetParent();
	return pWin; 
}

Post Reply