Search code examples
c++wxwidgets

wxWidgets exits before wxApp::OnInit is invoked


My wxApp derived class has its destructor invoked before its OnInit gets called. I think I tracked down where the error seems to rise. In the file appcmn.cpp, in method wxAppBase::Initialize, OnInitGui returns false. It seems this is due to the function returning a null top level window. I don't know if this is truly the problem though and I am a bit clueless either way what is going on.

  • OS: Windows 7 home 64bit
  • Compiler: cl 64bit from Visual Studio 2013 Express
  • wxWidgets Version: 3.0.2

I used the Visual Studio 2013 Express solution, included in the wxWidgets download, to build 64bit debug wxWidgets libraries.

Here is my code.

VoidCrafterApp.h

#ifndef VOIDCRAFTERAPP_H
#define VOIDCRAFTERAPP_H

#include "wx/wx.h"

class MainFrame;

class VoidCrafterApp : public wxApp
{
   MainFrame* m_pMainframe;

public:
   ~VoidCrafterApp();

   virtual bool OnInit();
};

DECLARE_APP(VoidCrafterApp);

#endif

VoidCrafterApp.cpp

#include "VoidCrafterApp.h"
#include "MainFrame.h"

IMPLEMENT_APP(VoidCrafterApp);

VoidCrafterApp::~VoidCrafterApp()
{
   bool wegothere = true; // This statement is executed
}

bool VoidCrafterApp::OnInit()
{
   m_pMainframe = new MainFrame("Hello World", wxPoint(50, 50), wxSize(450, 340));
   m_pMainframe->Show( true );

   return true;
}

MainFrame.h

#ifndef MAINFRAME_H
#define MAINFRAME_H

#include "wx/frame.h"
#include "wx/menu.h"

enum
{
   ID_Hello = 1
};

class MainFrame : public wxFrame
{
   // Top Menu Bar
   wxMenuBar* m_pMenuBar;

public:
   MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
private:
   void OnHello(wxCommandEvent& event);
   void OnExit(wxCommandEvent& event);
   void OnAbout(wxCommandEvent& event);

   wxDECLARE_EVENT_TABLE();
};

#endif

MainFrame.cpp

#include "MainFrame.h"
#include "wx/wx.h"

wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
EVT_MENU(ID_Hello, MainFrame::OnHello)
EVT_MENU(wxID_EXIT, MainFrame::OnExit)
EVT_MENU(wxID_ABOUT, MainFrame::OnAbout)
wxEND_EVENT_TABLE()

MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, wxID_ANY, title, pos, size)
{
    // Create the top menus
    wxMenu* pMenuFile = new wxMenu();
    pMenuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
    "Help string shown in status bar for this menu item");
    pMenuFile->AppendSeparator();
    pMenuFile->Append(wxID_EXIT);
    wxMenu* pMenuHelp = new wxMenu();
    pMenuHelp->Append(wxID_ABOUT);

    wxMenuBar *m_pMenuBar = new wxMenuBar;
    m_pMenuBar->Append(pMenuFile, "&File");
    m_pMenuBar->Append(pMenuHelp, "&Help");
    SetMenuBar(m_pMenuBar);

    CreateStatusBar();
    SetStatusText("Welcome to wxWidgets!");
}

void MainFrame::OnHello(wxCommandEvent& event)
{
    wxLogMessage("Hello world from wxWidgets!");
}

void MainFrame::OnExit(wxCommandEvent& event)
{
    Close(false);
}

void MainFrame::OnAbout(wxCommandEvent& event)
{
    wxMessageBox("This is a wxWidgets' Hello world sample",
        "About Hello World", wxOK | wxICON_INFORMATION);
}

Solution

  • OnInitGui() always returns true in wxMSW, unless overridden, and you don't seem to be overriding it, so it looks like you might have some kind of bad build, with a wrong virtual function being called (this can happen if you use headers from a newer version with an older library or something like this). So my advice would be to rebuild everything, i.e. both the library and your application, from scratch and see if it fixes the problem.

    If it doesn't, consider running the minimal sample which is very similar to your program. If it doesn't work, the problem is definitely with the build. If it does, then, by bisecting the difference between it and your code, you should be able to quickly find the crucial change that makes your program fail.