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.
Netzschleicher
Knows some wx things
Posts: 25 Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany
Post
by Netzschleicher » Thu Feb 07, 2019 5:08 pm
Hi at all,
i want to Show a wxFrame by clicking on a Button at my MainFrame. By the second Click, i want to close the wxFrame, or if the Frame was minimized to show them. Also the Frame can be closed on Close the Frame with the Close 'X' on the Frame.
But when the Frame was closed an i click on the Button again, i get an SIGSEGV Error at the Line 'if (memoryeditor->IsIconized()) {'. By watching the Pointer is seems to have a Adress but this is not valid?
What is my mistake?
Code: Select all
#ifndef MAINFRAME_H
#define MAINFRAME_H
//---------------------------------------------------------------------------------
#include "ui_mainframe.h"
//---------------------------------------------------------------------------------
class MemoryEditor;
//---------------------------------------------------------------------------------
class MainFrame : public Ui_MainFrame {
DECLARE_EVENT_TABLE()
private: // Attributes
MemoryEditor *memoryeditor;
public: // Attributes
public: // Constructor & Destructor
MainFrame (wxWindow *parent);
virtual ~MainFrame();
protected: // Event Methods
void onShowMemoryEditor (wxCommandEvent &event);
private: // Methods
public: // Methods
};
//---------------------------------------------------------------------------------
#endif // MAINFRAME_H
Code: Select all
#include "mainframe.h"
#include "memoryeditor.h"
//---------------------------------------------------------------------------------
BEGIN_EVENT_TABLE (MainFrame, wxFrame)
EVT_BUTTON (ID_BUTTON_SHOW_MEMORY_EDITOR, MainFrame::onShowMemoryEditor)
END_EVENT_TABLE()
//---------------------------------------------------------------------------------
MainFrame::MainFrame (wxWindow *parent) : Ui_MainFrame (parent) {
}
//---------------------------------------------------------------------------------
MainFrame::~MainFrame() {
wxDELETE (memoryeditor);
}
//---------------------------------------------------------------------------------
void MainFrame::onShowMemoryEditor (wxCommandEvent &event) {
if (memoryeditor == NULL) {
memoryeditor = new MemoryEditor (this);
}
if (memoryeditor != NULL) {
if (memoryeditor->IsIconized()) { <-- error after closing the wxFrame an want to show again
memoryeditor->Restore();
}
else if (memoryeditor->IsVisible()) {
memoryeditor->Close ();
}
else {
memoryeditor->Show();
}
}
}
//---------------------------------------------------------------------------------
Manolo
Can't get richer than this
Posts: 828 Joined: Mon Apr 30, 2012 11:07 pm
Post
by Manolo » Thu Feb 07, 2019 5:15 pm
I guess you don't update "memoryeditor" pointer after memoryeditor->Close()
Can't know, not enough code.
Netzschleicher
Knows some wx things
Posts: 25 Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany
Post
by Netzschleicher » Thu Feb 07, 2019 5:17 pm
What do you mean with update?
The memoryeditor Pointer is a private Member of the Main Frame class.
What more Code do you need?
doublemax
Moderator
Posts: 19160 Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2
Post
by doublemax » Thu Feb 07, 2019 5:26 pm
The default behavior of a wxFrame is to destroy itself when it's closed. After that the pointer "memoryeditor" is invalid.
Use the source, Luke!
Manolo
Can't get richer than this
Posts: 828 Joined: Mon Apr 30, 2012 11:07 pm
Post
by Manolo » Thu Feb 07, 2019 5:27 pm
If you close that other frame and don't set memoryeditor = NULL (which is done with wxDELETE(memoryeditor) ) then the next time you click the button the memoryeditor->IsIconized() branch is executed with an invalid pointer.
Netzschleicher
Knows some wx things
Posts: 25 Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany
Post
by Netzschleicher » Thu Feb 07, 2019 5:29 pm
Can the Pointer set to NULL, or how can i test if the Pointer is valid?
Manolo
Can't get richer than this
Posts: 828 Joined: Mon Apr 30, 2012 11:07 pm
Post
by Manolo » Thu Feb 07, 2019 5:43 pm
There are two points where you must NULL that pointer:
a) Right after memoryeditor->Close()
b) In your MemoryEditor ctor pass a pointer to the main frame. Have a "make memoryeditor NULL" method in the main frame.
When the MemoryEditor closes (handle this event), call that method in the main frame: myMainFrame->SetEPNull() ;
doublemax
Moderator
Posts: 19160 Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2
Post
by doublemax » Thu Feb 07, 2019 5:47 pm
Use the source, Luke!
Netzschleicher
Knows some wx things
Posts: 25 Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany
Post
by Netzschleicher » Thu Feb 07, 2019 6:58 pm
what do you think about this construct?
Code: Select all
if ((memoryeditor == NULL) || (memoryeditor->IsBeingDeleted() == true)) {
memoryeditor = new MemoryEditor (this);
}
Manolo
Can't get richer than this
Posts: 828 Joined: Mon Apr 30, 2012 11:07 pm
Post
by Manolo » Thu Feb 07, 2019 7:04 pm
By the time IsBeingDeleted() is called, you can't be sure that the frame still exists, so that pointer can point to an invalid instance.
Netzschleicher
Knows some wx things
Posts: 25 Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany
Post
by Netzschleicher » Thu Feb 07, 2019 7:06 pm
Ok. I thought this can be an easy solution.
Netzschleicher
Knows some wx things
Posts: 25 Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany
Post
by Netzschleicher » Tue Feb 12, 2019 5:34 pm
So, a few days later, i have tested Manolos suggested solution.
It works very fine.
Following the Code i used now.
Code: Select all
#ifndef MAINFRAME_H
#define MAINFRAME_H
//---------------------------------------------------------------------------------
#include "ui_mainframe.h"
//---------------------------------------------------------------------------------
class MainFrame : public Ui_MainFrame {
DECLARE_EVENT_TABLE()
private: // Attributes
public: // Attributes
public: // Constructor & Destructor
MainFrame (wxWindow *parent);
virtual ~MainFrame();
protected: // Event Methods
void onShowMemoryEditor (wxCommandEvent &event);
private: // Methods
public: // Methods
void SetMemoryEditorZero();
};
//---------------------------------------------------------------------------------
#endif // MAINFRAME_H
Code: Select all
#include "mainframe.h"
#include "memoryeditor.h"
//---------------------------------------------------------------------------------
BEGIN_EVENT_TABLE (MainFrame, wxFrame)
EVT_BUTTON (ID_BUTTON_SHOW_MEMORY_EDITOR, MainFrame::onShowMemoryEditor)
END_EVENT_TABLE()
//---------------------------------------------------------------------------------
MainFrame::MainFrame (wxWindow *parent) : Ui_MainFrame (parent) {
SetMemoryEditorZero();
}
//---------------------------------------------------------------------------------
MainFrame::~MainFrame() {
}
//---------------------------------------------------------------------------------
void MainFrame::onShowMemoryEditor (wxCommandEvent &event) {
if (memoryeditor == nullptr) {
memoryeditor = new MemoryEditor (this);
}
if (memoryeditor != nullptr) {
if (memoryeditor->IsIconized()) {
memoryeditor->Restore();
memoryeditor->Raise();
}
else if (memoryeditor->IsVisible()) {
memoryeditor->Close ();
}
else {
memoryeditor->Show();
memoryeditor->Raise();
}
}
}
//---------------------------------------------------------------------------------
void MainFrame::SetMemoryEditorZero() {
memoryeditor = nullptr;
}
//---------------------------------------------------------------------------------
Code: Select all
#ifndef MEMORYEDITOR_H
#define MEMORYEDITOR_H
//---------------------------------------------------------------------------------
#include "ui_memoryeditor.h"
//---------------------------------------------------------------------------------
class MainFrame;
//---------------------------------------------------------------------------------
class MemoryEditor : public Ui_MemoryEditor {
private: // Attributes
MainFrame *mainframe;
public: // Attributes
public: // Constructor & Destructor
MemoryEditor (wxWindow *parent);
virtual ~MemoryEditor();
protected: // Event Methods
private: // Methods
public: // Methods
};
//---------------------------------------------------------------------------------
extern MemoryEditor *memoryeditor;
//---------------------------------------------------------------------------------
#endif // MEMORYEDITOR_H
Code: Select all
#include "memoryeditor.h"
#include "mainframe.h"
//---------------------------------------------------------------------------------
MemoryEditor *memoryeditor;
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
MemoryEditor::MemoryEditor (wxWindow *parent) : Ui_MemoryEditor (parent) {
MainFrame *mainframe = dynamic_cast<MainFrame *> (parent);
}
//---------------------------------------------------------------------------------
MemoryEditor::~MemoryEditor() {
mainframe->SetMemoryEditorZero();
}
//---------------------------------------------------------------------------------