Page 1 of 1

Crash when create Dialog after Destroy()

Posted: Fri May 18, 2018 9:05 pm
by saifcoder
I have two Dialogs, with one button on each Dialog, i m just traying to Create and Show the Dialog, then Destroy it, and Create and Show it again !

Dialog 1, Button 1

Code: Select all

	if (!DIALOG_2_IS_CONSTRUCTED)
	{
		OBJ_DIALOG_2 = new DIALOG_2();
		
		DIALOG_2_IS_CONSTRUCTED = true;
	}
	
	OBJ_DIALOG_2 ->Show(true);
	
	OBJ_DIALOG_2 ->SetFocus();
	
	DIALOG_2_IS_CONSTRUCTED = true;
Dialog 2, Button 2

Code: Select all

	DIALOG_2_IS_CONSTRUCTED = false;
		
		OBJ_DIALOG_2->Destroy();
	
1 - Click on Button 1 : Dialog 2 Created and Show correctly !
2 - Click on Button 2 : Dialog 2 Destroy correctly !
3 - Click on Button 1 : App Crash !

I don't have a Debug Build.. So why App Crash ?

Thanks,

Re: Crash when create Dialog after Destroy()

Posted: Fri May 18, 2018 9:29 pm
by doublemax
First of all: You should use dialogs only when you need a modal dialog. If you want a non-modal "dialog", don't use a wxDialog, use a wxFrame.

Apart from that, show more (real) code in context.

Re: Crash when create Dialog after Destroy()

Posted: Sun May 20, 2018 12:32 am
by saifcoder
Thank you doublemax, i change it to wxFrame :D

The crash is happen because the incorrect parent !, the parent is the same Frame !, i know basically is incorrect, but why can create the Frame only once ?

Code: Select all

FRAME_2 :: FRAME_2() : wxFrame(  ---> OBJ_FRAME_2 <--- , ID_FRAME_2, "FRAME 2", wxPoint(50, 50), wxSize(450, 450)...
Full shortcut code :

Code: Select all

#include <wx/wx.h>

int ID_FRAME_1 = 5000;
int ID_FRAME_2 = 5001;
int ID_BOUTON_1 = 5002;
int ID_BOUTON_2 = 5003;

bool FRAME_2_CONSTRUCTED = false;

class FRAME_1 : public wxFrame
{
    public:
		
        FRAME_1 ();
		
        virtual ~FRAME_1();
		
        void BOUTON_1_CLICK(wxCommandEvent &event);

    private:
		DECLARE_NO_COPY_CLASS(FRAME_1)
        DECLARE_EVENT_TABLE()
};

class FRAME_2 : public wxFrame
{
    public:
		
        FRAME_2 ();
		
        virtual ~FRAME_2();
		
        void BOUTON_2_CLICK(wxCommandEvent &event);

    private:
		DECLARE_NO_COPY_CLASS(FRAME_2)
        DECLARE_EVENT_TABLE()
};

FRAME_1 *OBJ_FRAME_1;
FRAME_2 *OBJ_FRAME_2;

wxButton* OBJ_BUTTON_1;
wxButton* OBJ_BUTTON_2;

FRAME_1 :: FRAME_1() : wxFrame(NULL, ID_FRAME_1, "FRAME 1",wxPoint(50, 50),wxSize(450, 450), wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN) 
{

    wxPanel *P = new wxPanel(this, wxID_ANY);
	
	OBJ_BUTTON_1 = new wxButton (P, ID_BOUTON_1, wxT("Show Frame 2"), wxPoint(20,30), wxSize(120, 35));
	
	Centre();
}

BEGIN_EVENT_TABLE(FRAME_1, wxFrame)
	
	EVT_BUTTON(ID_BOUTON_1, FRAME_1::BOUTON_1_CLICK)
	
END_EVENT_TABLE()

FRAME_2 :: FRAME_2() : wxFrame(OBJ_FRAME_2, ID_FRAME_2, "FRAME 2", wxPoint(50, 50), wxSize(450, 450),
	wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN) 
{

    wxPanel *P = new wxPanel(this, wxID_ANY);
	
	OBJ_BUTTON_2 = new wxButton (P, ID_BOUTON_2, wxT("Hide Frame 2"), wxPoint(20,30), wxSize(120, 35));
	
	Centre();
}

BEGIN_EVENT_TABLE(FRAME_2, wxFrame)
	
	EVT_BUTTON(ID_BOUTON_2, FRAME_2::BOUTON_2_CLICK)
	
END_EVENT_TABLE()

FRAME_1::~FRAME_1()
{

}

FRAME_2::~FRAME_2()
{
	FRAME_2_CONSTRUCTED = false;
}

class MyApp : public wxApp
{
    public:
		
        MyApp();
		
		~MyApp();
		
		virtual bool OnInit();
		
        virtual int OnExit();
        
	private:
		DECLARE_NO_COPY_CLASS(MyApp)
};

DECLARE_APP(MyApp);

IMPLEMENT_APP(MyApp);

MyApp::MyApp()
{

}

MyApp::~MyApp()
{

}

int MyApp::OnExit()
{
	return 0;
}

bool MyApp::OnInit()
{
	
	if (!wxApp::OnInit())
		return false;

	OBJ_FRAME_1 = new FRAME_1();
	
    OBJ_FRAME_1->Show();
	
	SetTopWindow(OBJ_FRAME_1);
	
	OBJ_FRAME_1->Refresh();
	
    return true;
}

void FRAME_1::BOUTON_1_CLICK(wxCommandEvent &event)
{
	event.Skip();
	
		// -------------
		
		if (!FRAME_2_CONSTRUCTED)
		{
			OBJ_FRAME_2 = new FRAME_2();
		  
			FRAME_2_CONSTRUCTED = true;
		}
	   
		OBJ_FRAME_2->Show(true);
	   
		OBJ_FRAME_2->SetFocus();

		// -------------
	
}

void FRAME_2::BOUTON_2_CLICK(wxCommandEvent &event)
{
	event.Skip();
	
		// -------------
		
		if (FRAME_2_CONSTRUCTED)
		{
			FRAME_2_CONSTRUCTED = false;
			
			OBJ_FRAME_2->Destroy();
		}

		// -------------

}
Thank you,

Re: Crash when create Dialog after Destroy()

Posted: Sun May 20, 2018 6:50 am
by doublemax
Of course you can't use OBJ_FRAME_2 as the parent for Frame2. If it works the first time, then because the pointer is still NULL.

And why are you checking the FRAME_2_CONSTRUCTED flag in FRAME_2::BOUTON_2_CLICK? This is a method from FRAME_2, so it must be constructed. Actually you only have to call Close() in that method, nothing else.

Re: Crash when create Dialog after Destroy()

Posted: Sun May 20, 2018 7:15 pm
by saifcoder
And why are you checking the FRAME_2_CONSTRUCTED flag in FRAME_2::BOUTON_2_CLICK? This is a method from FRAME_2
Oh! Yeah! My Stupid! Sorry :)

Code: Select all

void FRAME_2::BOUTON_2_CLICK(wxCommandEvent &event)
{
   event.Skip();
   Close();
}
Thank you doublemax,