wxFrame used as Splash crashes 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
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

wxFrame used as Splash crashes

Post by Natulux »

Hey
I wanted an OnClick event for a notification message, which I dont get from wxSplashScreen, so I made it myself (With vs2015, wxWidgets 3.1.0, win10x64).
A frame with a Panel and a StaticText as message, as a child of a parent frame. It works all fine and dandy until I stress it to much and it crashes.

Using the frame derived class as notification class:

Code: Select all

MyMsg::MyMsg(wxPoint pos, wxSize size, wxString title, wxString msg, wxWindow *parent, int timeout)
: wxFrame(parent, wxID_ANY, title, pos, size, wxSTAY_ON_TOP)
{
	wxFlexGridSizer *fgs_main = new wxFlexGridSizer(1);

	wxPanel *pn_body = new wxPanel(this);
	wxFlexGridSizer *fgs_body = new wxFlexGridSizer(1);

		mst_info = new wxStaticText(pn_body, ID_TMP_STATIC_INFO, msg);

		fgs_body->Add(mst_info, 1, wxALL|wxEXPAND, 10);

		fgs_body->AddGrowableCol(0,1);
		fgs_body->AddGrowableRow(0,1);

		pn_body->SetSizer(fgs_body);

		mst_info->Bind(wxEVT_LEFT_DOWN, &MyMsg::OnMouse, this);
		mst_info->Connect(ID_TMP_STATIC_INFO, wxEVT_LEFT_DOWN, wxMouseEventHandler(MyMsg::OnMouse), NULL, this);

	fgs_main->Add(pn_body, 1, wxEXPAND);
	fgs_main->AddGrowableCol(0, 1);
	fgs_main->AddGrowableRow(0, 1);

	this->SetSizer(fgs_main);

	mt_timer = new wxTimer(this, ID_TMP_TIMER);
	mt_timer->Start(timeout);

	this->SetFocus();
	this->Raise();

Code: Select all

	MyMsg *msg = new MyMsg(wxDefaultPosition, wxDefaultSize, "infoskopMsgNotification", sMsgText, NULL, lSplashOnTime);
	//[...]
	msg->SetSize(GetTextPixelLength(sMsgText, font, msg), 50);
	//[...]
	msg->SetPosition(wxPoint(x, y));
	msg->Show();
The notification frame can be shown like 5-6 times at once and is destroyed by a timer after some seconds.
I gave the StaticText an OnClick to destroy itself when clicked upon.

Code: Select all

void MyMsg::OnMouse(wxMouseEvent &event)
{
	Close(true);
}

void MyMsg::OnTimer(wxTimerEvent &event)
{
	mt_timer->Stop();
	Close(true);
}
But everytime the frame is beeing created, it gets its own icon in the task bar. And there, I can close the frame too (windows standard). And if I mix closing some open notification frames over the icon, by clicking on some and by timers running out, I get a program crash after some trials.

EDIT: A quick test showed: I can get a crash even without using the icon close. Once the first frames start closing, creating new frames or clicking on a frame to close it will very likely generate a program crash.

Some ideas, what might cause this?
Greetz
Natu
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxFrame used as Splash crashes

Post by doublemax »

I can't spot an obvious reason for a crash, so just some general hints / questions:

What do you use as parent for these frames? I would suggest to use NULL.

You don't show the destructor of the frame, do you unbind the event handlers? Do you destroy the timer?

Can you get a backtrace for the crash?
Use the source, Luke!
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxFrame used as Splash crashes

Post by PB »

Natulux wrote:But everytime the frame is beeing created, it gets its own icon in the task bar.
Have you tried to create the frame with wxFRAME_NO_TASKBAR style?

Regarding the crash, what about using a stack-based non-shared (ID-wise) timer?
In MyMsg class declaration

Code: Select all

wxTimer m_timer;
and in its ctor

Code: Select all

 m_timer.StartOnce(timeout);
 m_timer.Bind(wxEVT_TIMER, &MyMsg::OnTimer, this);
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

Re: wxFrame used as Splash crashes

Post by Natulux »

Thank you for your good suggestions, but I found my mistake (and doubleMax guessed quite right):
I didn't stop the timer, when destroying the frame on click or via task bar, so the timer was about to destroy a frame that was already destroyed.
That teaches me to always stop, cleanup and delete in OnClose or the destructor.

But now you mentioned it:
PB wrote:what about using a stack-based non-shared (ID-wise) timer?
Im not completly getting, what this timer is for. It is a timer, which cant exists outside of its namespace - so you dont have to delete it at least. But what do you mean by non-shared?

Greetings
Natu
Post Reply