Destroy call on wxHyperlinkCtrl crashes the application

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
deepti
Earned some good credits
Earned some good credits
Posts: 115
Joined: Tue Jul 17, 2018 5:38 pm

Destroy call on wxHyperlinkCtrl crashes the application

Post by deepti »

Hi All,

I have an instance of a wxScrolledWindow, which contains several wxBoxSizer instances.
Each wxBoxSizer contains a wxCollapsiblePane and a wxHyperlinkCtrl ("Remove" link). Please refer to attachment. That is how it looks like.
When the "Remove" hyper-link is clicked, the wxCollapsiblePane associated with it (and it's child controls) needs to be removed and also the "Remove" link itself.
For this, I have the following code, which works fine on Windows, but crashes on Mac. If i comment out the line "removeLink->Destroy();", it does not crash, but the link remains, which i obviously do not want.
The wxHyperlinkCtrl is actually customized in order to store the ID of the associated wxCollapsiblePane.
The "m_metaDataControlsbox" is the outermost sizer, which contains all the other wxBoxSizer instances.
What is it that I am doing wrong here? Please help!

Code: Select all

void PropertiesDialog::OnRemoveMetadataControls(wxHyperlinkEvent& event)
{
	bool bRemoved = false;

	int id = event.GetId();
	customHyperLinkCtrl* removeLink = (customHyperLinkCtrl*)FindWindow(id);
	int siblingCollPaneID = 0;
	siblingCollPaneID = removeLink->getSiblingCollPaneID();
	metadataSetCollapsiblePane* cpWindow = (metadataSetCollapsiblePane*)FindWindow(siblingCollPaneID);

	
	if (cpWindow != NULL)
	{	

			wxWindow* cpPane = cpWindow->GetPane();
			wxWindowList cpChildren = cpPane->GetChildren();
			for (int i = 0; i < cpChildren.GetCount(); i++)
			{
				wxWindow* w = cpChildren[i];
				if (w != NULL)
					w->Destroy();
			}
			cpWindow->Destroy();

			removeLink->Destroy();

			wxSizer* cpContainer = cpWindow->GetContainingSizer();
			m_metaDataControlsbox->Remove(cpContainer);
	}
}
issue.jpg
issue.jpg (35.33 KiB) Viewed 853 times
User avatar
doublemax
Moderator
Moderator
Posts: 19111
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Destroy call on wxHyperlinkCtrl crashes the application

Post by doublemax »

Just deleting the metadataSetCollapsiblePane should be enough, it will destroy all its children (and grandchildren etc).

But as you're inside an event handler for the wxHyperlinkCtrl, you should not cut the branch you're sitting on.

Use wxAppConsole::ScheduleForDestruction to destroy the pane:
https://docs.wxwidgets.org/trunk/classw ... 22f9de9d90
Use the source, Luke!
deepti
Earned some good credits
Earned some good credits
Posts: 115
Joined: Tue Jul 17, 2018 5:38 pm

Re: Destroy call on wxHyperlinkCtrl crashes the application

Post by deepti »

Thank you @doublemax.
Use wxAppConsole::ScheduleForDestruction to destroy the pane:
Are you referring to scheduling the destruction of the "Remove" hyperlink here?
User avatar
doublemax
Moderator
Moderator
Posts: 19111
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Destroy call on wxHyperlinkCtrl crashes the application

Post by doublemax »

As the hyperlink is a child of the pane, i don't think you have to destroy it individually. It'll get destroyed anyway when the pane gets destroyed.
Use the source, Luke!
deepti
Earned some good credits
Earned some good credits
Posts: 115
Joined: Tue Jul 17, 2018 5:38 pm

Re: Destroy call on wxHyperlinkCtrl crashes the application

Post by deepti »

The hyperlink is not the child of the pane. It is a sibling, in the sense the pane and hyperlink are both in the same sizer.
Will just hiding the hyperlink help in my case? Once the dialog is closed, any control which has not been explicitly destroyed will anyway be destroyed automatically, isn't it?
User avatar
doublemax
Moderator
Moderator
Posts: 19111
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Destroy call on wxHyperlinkCtrl crashes the application

Post by doublemax »

The hyperlink is not the child of the pane. It is a sibling, in the sense the pane and hyperlink are both in the same sizer.
Ok, then you should also destroy it using ScheduleForDestruction.
Will just hiding the hyperlink help in my case? Once the dialog is closed, any control which has not been explicitly destroyed will anyway be destroyed automatically, isn't it?
Yes, but it sounds dirty. I wouldn't like to have invisible zombie controls laying around :)
Use the source, Luke!
deepti
Earned some good credits
Earned some good credits
Posts: 115
Joined: Tue Jul 17, 2018 5:38 pm

Re: Destroy call on wxHyperlinkCtrl crashes the application

Post by deepti »

Great!! Thanks a lot, my savior! :D
Post Reply