How to create a wxWindow-pointer without a wxApp

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
Nico
Knows some wx things
Knows some wx things
Posts: 31
Joined: Sun Nov 07, 2010 5:19 pm

How to create a wxWindow-pointer without a wxApp

Post by Nico » Mon Jul 28, 2014 9:00 pm

Hello,

I am creating unit test for an application that uses static wxWidgets 3.0.0 libraries on windows. The project that contains and runs the tests is linked with the libraries, but it is a regular console application, meaning i don't have a wxApp or a wxWindow. Now one of my test requires me to create an object that takes a pointer to a wxPanel as one of its arguments. I tried to create a seperate wxPanel for this, but they don't seem to be able to exist without a wxWindow (what makes sence). Unfortunatly I don't seem to manage creating a wxWindow without making the whole thing into a wxApp, which I can't do if i want to run the unittests.

This might be a noob question, but could somebody please tell me how I can best create a wxWindow without having a wxApp? Do I need additional includes? Should I initialize something first?

Kind regards, Nico

Manolo
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 698
Joined: Mon Apr 30, 2012 11:07 pm

Re: How to create a wxWindow-pointer without a wxApp

Post by Manolo » Mon Jul 28, 2014 10:50 pm

It's not possible.
A window receives messages (size, mouse, paint, etc). And these messages are handled by wxApp and, if required, redirected to your own handler.

You can take a look at 'test' folder of your wxWidgets folder, and see there how CPPUNIT (an external, painful, library) is used for testing.

Nico
Knows some wx things
Knows some wx things
Posts: 31
Joined: Sun Nov 07, 2010 5:19 pm

Re: How to create a wxWindow-pointer without a wxApp

Post by Nico » Tue Jul 29, 2014 9:50 am

Ok, so like a wxPanel requires a wxWindow, a wxWindow requires a wxApp and there is no way around it.

Would it be possible to create a wxApp inside the already running testcase or does wxApp need to be the class the first one there (as I normally do)? In other words, if I need to create a wxApp in order to create a wxWindow in order to create the wxPanel that I need, could I do that? And if so: how? (the only way I know to get a wxApp is to ask CodeBlocks to automatically create one for me and then modify it)

Kind regards, Nico

Nico
Knows some wx things
Knows some wx things
Posts: 31
Joined: Sun Nov 07, 2010 5:19 pm

Re: How to create a wxWindow-pointer without a wxApp

Post by Nico » Thu Jul 31, 2014 8:27 pm

Hello,

I gave it a try, but of course I ran into some problems that I don't understand. My attempts did however enable me to pinpoint the problem better.

I created two classes to stand in for the app and the main window.

Code: Select all

#include "MyApp.h"

#include <wx/image.h>

MyApp::MyApp()
{
    MyDialog Dlg(0);
    windowPointer = &Dlg;
}

MyApp::~MyApp()
{

}

bool MyApp::OnInit()
{
    //(*AppInitialize
    bool wxsOK = true;
    wxInitAllImageHandlers();
    if ( wxsOK )
    {
    	MyDialog Dlg(0);
    	windowPointer = &Dlg;
    	SetTopWindow(&Dlg);
    	Dlg.ShowModal();
    	wxsOK = false;
    }
    //*)
    return wxsOK;
}

MyDialog* MyApp::getWindowPointer()
{
    return windowPointer;
}

Code: Select all

#include "MyMain.h"
#include <wx/msgdlg.h>
#include <wx/settings.h>
#include <wx/font.h>
#include <wx/intl.h>
#include <wx/string.h>


BEGIN_EVENT_TABLE(MyDialog,wxDialog)
    //(*EventTable(MyDialog)
    //*)
END_EVENT_TABLE()

MyDialog::MyDialog(wxWindow* parent,wxWindowID id)
{
    Create(parent, id, _("wxWidgets app"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("id"));
    MainWindowSizer = new wxBoxSizer(wxVERTICAL);
    schema = new Schema(this);
    MainWindowSizer->Add(schema, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
    SetSizer(MainWindowSizer);
    MainWindowSizer->Fit(this);
    MainWindowSizer->SetSizeHints(this);
}

Schema* MyDialog::getSchemaPointer()
{
    return schema;
}

MyDialog::~MyDialog()
{
    //(*Destroy(xDialog)
    //*)
}
My testcase:

Code: Select all

#include "Module.h"

TEST(creating_the_Module)
{
    // create an instance of wxApp in order to get an instance of MyMain, in order to get an instance of Schema (wxPanel).
    MyApp* app = new MyApp(); 
    // Try to create an instance of an other wxPanel
    Module* module = new Module(app->getWindowPointer()->getSchemaPointer(),9); 
    // if we can ask it something, it must exist
    CHECK(module->getModuleNumber() == 9);
}
I added some logging to see how far I get and it seems the whole thing crashes when I reach the very first line of the constructor of the Module class, which is very standard:
"Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL|wxFULL_REPAINT_ON_RESIZE, _T("wxID_ANY"));"

Parent is a pointer to an instance of MyMain ( checked if it crashes upon the call to getSchemaPointer in a separate line, but it does not). Most likely there is something missing in MyMain, but what could this be?

Kind regards, Nico

User avatar
doublemax
Moderator
Moderator
Posts: 14044
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to create a wxWindow-pointer without a wxApp

Post by doublemax » Thu Jul 31, 2014 8:55 pm

I seriously doubt it will work this way anyway, but there is one critical error:

Code: Select all

MyDialog Dlg(0);
windowPointer = &Dlg;
MyDialog is created on the stack, so the windowPointer will be invalid after the ctor is done.
Use the source, Luke!

Post Reply