Error with creating a tab in wxAuiNotebook

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
tengai
Knows some wx things
Knows some wx things
Posts: 32
Joined: Fri May 11, 2018 6:49 pm

Error with creating a tab in wxAuiNotebook

Post by tengai »

Hello,

Using Windows wxWidgets 3.1.1 and I have the following code:
wxPOMTabPanel::wxPOMTabPanel(wxWindow* parent) : wxPanel(parent, wxID_ANY)
{
wxSizer* sizerV = new wxBoxSizer(wxVERTICAL);

notebook = new wxAuiNotebook(this, eNoteBookCtrl);
notebook->AddPage(new wxPanel(notebook), "Test", true, wxNullBitmap);

sizerV->Add(notebook, wxSizerFlags(1).Expand());
SetSizerAndFit(sizerV);
}
and at call to: SetSizerAndFit(sizerV) I get error (wxWidgets Debug Alert):

"..\..\src\msw\bitmap.cpp(752): assert ""w > 0 && h > 0"" failed in wxBitmap::DoCreate(): invalid bitmap size"

Any ideas?

Thanks,

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

Re: Error with creating a tab in wxAuiNotebook

Post by doublemax »

Are you sure the assert is caused by that code? Passing wxNullBitmap to the AddPage() call should be safe.

Check the call stack/backtrace and see which bitmap is creating the assert.
Use the source, Luke!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Error with creating a tab in wxAuiNotebook

Post by ONEEYEMAN »

Hi,
In addition to doublemax' response:
Please check that the wxBitmap (the one that cases the assert) was created successfully (call wxBitmap.IsOk() should succeed).

Thank you.
tengai
Knows some wx things
Knows some wx things
Posts: 32
Joined: Fri May 11, 2018 6:49 pm

Re: Error with creating a tab in wxAuiNotebook

Post by tengai »

The problem shows itself in code:

Code: Select all

bool wxBitmap::DoCreate(int w, int h, int d, WXHDC hdc)
{
    UnRef();

    wxCHECK_MSG( w > 0 && h > 0, false, wxT("invalid bitmap size") );
arg, 'w' == '0' and arg, 'h' == 25


Call Stack:
wxITK.exe!wxBitmap::DoCreate(int w, int h, int d, HDC__ * hdc) Line 752 C++
wxITK.exe!wxBitmap::Create(int width, int height, const wxDC & dc) Line 743 C++
wxITK.exe!wxAuiTabContainer::Render(wxDC * raw_dc, wxWindow * wnd) Line 429 C++
wxITK.exe!wxAuiTabCtrl::OnPaint(wxPaintEvent & __formal) Line 1024 C++
wxITK.exe!wxAppConsoleBase::HandleEvent(wxEvtHandler * handler, void (wxEvent &) * func, wxEvent & event) Line 658 C++
wxITK.exe!wxAppConsoleBase::CallEventHandler(wxEvtHandler * handler, wxEventFunctor & functor, wxEvent & event) Line 670 C++
wxITK.exe!wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase & entry, wxEvtHandler * handler, wxEvent & event) Line 1398 C++
wxITK.exe!wxEventHashTable::HandleEvent(wxEvent & event, wxEvtHandler * self) Line 1004 C++
wxITK.exe!wxEvtHandler::TryHereOnly(wxEvent & event) Line 1593 C++
wxITK.exe!wxEvtHandler::TryBeforeAndHere(wxEvent & event) Line 3873 C++
wxITK.exe!wxEvtHandler::ProcessEventLocally(wxEvent & event) Line 1526 C++
wxITK.exe!wxEvtHandler::ProcessEvent(wxEvent & event) Line 1499 C++
wxITK.exe!wxEvtHandler::SafelyProcessEvent(wxEvent & event) Line 1617 C++
wxITK.exe!wxWindowBase::HandleWindowEvent(wxEvent & event) Line 1540 C++
wxITK.exe!wxWindow::HandlePaint() Line 4934 C++
wxITK.exe!wxWindow::MSWHandleMessage(__int64 * result, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 2989 C++
wxITK.exe!wxWindow::MSWWindowProc(unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 3758 C++
wxITK.exe!wxWndProc(HWND__ * hWnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 2846 C++
user32.dll!0000000076cd9bbd() Unknown
user32.dll!0000000076cd729b() Unknown
user32.dll!0000000076cd67e9() Unknown
ntdll.dll!0000000076f4b5ef() Unknown
user32.dll!0000000076cd3caa() Unknown
user32.dll!0000000076cd277a() Unknown
wxITK.exe!wxWindow::Update() Line 1667 C++
> wxITK.exe!wxTabFrame::DoSizing()Line 1563 C++

In auibook.cpp, at stack call, wxAuiTabContainer::Render, this->m_rect.width == 0 and this->m_rect.height==25

And likewise, at stack call wxTabFrame::DoSizing, this->m_tab_rect.width == 0 and this->m_tab_rect.height==25.

It is unclear why 'width' is not being initialized to a value greater than '0'.


Thanks,

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

Re: Error with creating a tab in wxAuiNotebook

Post by doublemax »

It seems that m_rect contains (0,25), the error must lie somewhere else, but it's hard to tell where.

Did the AUI code in your program ever work, or is this your first try? If it did work at some time, try commenting out code your latest changes until it works again.
Use the source, Luke!
tengai
Knows some wx things
Knows some wx things
Posts: 32
Joined: Fri May 11, 2018 6:49 pm

Re: Error with creating a tab in wxAuiNotebook

Post by tengai »

Here is a simple test case that will duplicate this issue with wxAuiNoteBook:

Code: Select all

#include <wx/wx.h>
#include <wx/aui/auibook.h>

class MyApp : public wxApp
{
public:
	    virtual bool OnInit();
};

wxIMPLEMENT_APP(MyApp);


class MyFrame : public wxFrame
{
public:
	MyFrame();

	void showNoteBook();
};

class MyTabPanel : public wxPanel
{
public:
	MyTabPanel(wxWindow* parent);
};


bool MyApp::OnInit()
{
	MyFrame* frame = new MyFrame();

	frame->Show(true);
	frame->showNoteBook();

	return true;
}

MyFrame::MyFrame() : wxFrame(NULL, wxID_ANY, "Test AuiNoteBook")
{
}

void MyFrame::showNoteBook()
{
	wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
	MyTabPanel* tabPanel = new MyTabPanel(this);

	sizer->Add(new wxStaticText(this, wxID_ANY, "Messages"), wxSizerFlags().CenterHorizontal());
	sizer->Add(tabPanel, wxSizerFlags(1).Expand());

	this->SetSizer(sizer);
	this->SendSizeEvent();
}

MyTabPanel::MyTabPanel(wxWindow* parent) : wxPanel(parent, wxID_ANY)
{
	wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
	wxAuiNotebook* notebook = new wxAuiNotebook(this, wxID_ANY);

	notebook->AddPage(new wxPanel(notebook), "Test", true, wxNullBitmap);

	sizer->Add(notebook, wxSizerFlags(1).Expand());
	this->SetSizerAndFit(sizer);
}
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Error with creating a tab in wxAuiNotebook

Post by doublemax »

Change SetSizerAndFit to SetSizer.

Code: Select all

//this->SetSizerAndFit(sizer);
this->SetSizer(sizer);
SetSizerAndFit only makes sense if "this" is a toplevel window like a wxFrame or wxDialog.

Although i have to admit that i'm not sure why that leads to a crash, but i was too lazy to research it any further.
Use the source, Luke!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Error with creating a tab in wxAuiNotebook

Post by ONEEYEMAN »

Doublemax,
doublemax wrote: Change SetSizerAndFit to SetSizer.

Code: Select all

//this->SetSizerAndFit(sizer);
this->SetSizer(sizer);
SetSizerAndFit only makes sense if "this" is a toplevel window like a wxFrame or wxDialog.

Although i have to admit that i'm not sure why that leads to a crash, but i was too lazy to research it any further.
;-)

People are lazy in general.

Thank you.
tengai
Knows some wx things
Knows some wx things
Posts: 32
Joined: Fri May 11, 2018 6:49 pm

Re: Error with creating a tab in wxAuiNotebook

Post by tengai »

Yes, this fixed the issue. Thanks!
SetSizerAndFit only makes sense if "this" is a toplevel window like a wxFrame or wxDialog.
Is wxPanel not considered a toplevel window? Because I use SetSizerAndFit with all my Panels.
Last edited by tengai on Fri May 25, 2018 4:21 pm, edited 1 time in total.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Error with creating a tab in wxAuiNotebook

Post by ONEEYEMAN »

Hi,
wxPanel is not wxFrame or wxDialog. It can be used in place of wxDialog, but it can be considered weird as usually dialogs can be shown modally and they have all those regular window decorations.

Thank you.
Last edited by ONEEYEMAN on Fri May 25, 2018 4:30 pm, edited 1 time in total.
tengai
Knows some wx things
Knows some wx things
Posts: 32
Joined: Fri May 11, 2018 6:49 pm

Re: Error with creating a tab in wxAuiNotebook

Post by tengai »

wxPanel is not wxFrame or wxDialog?
Sorry, are you asking me the question?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Error with creating a tab in wxAuiNotebook

Post by ONEEYEMAN »

Hi,
Sorry no. I was just stating the fact.

Thank you.
tengai
Knows some wx things
Knows some wx things
Posts: 32
Joined: Fri May 11, 2018 6:49 pm

Re: Error with creating a tab in wxAuiNotebook

Post by tengai »

Ok...

For clarity, what is the technical difference between SetSizerAndFit() and SetSizer() and is this size information ever communicated to its parent?

And if SetSizerAndFit() is only to be called on TopLevel windows then why is this method defined at wxWindowBase as opposed to wxTopLevelWindow?

Thanks,

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

Re: Error with creating a tab in wxAuiNotebook

Post by doublemax »

tengai wrote:For clarity, what is the technical difference between SetSizerAndFit() and SetSizer()
I think that's pretty well explained in the doc: http://docs.wxwidgets.org/trunk/classwx ... 6cdfb6b73c
...and is this size information ever communicated to its parent?
Not directly. Parents don't care about the size of their children, but if the child is in a sizer hierarchy, it will (try to) obey the minimum size set by the call.
And if SetSizerAndFit() is only to be called on TopLevel windows then why is this method defined at wxWindowBase as opposed to wxTopLevelWindow?
There are cases where calling SetSizerAndFit() on a panel makes sense and usually it shouldn't do any harm - as you noticed yourself. It's just that AUI doesn't like it for some reason. But AUI is a beast anyway.

The reason why calling SetSizerAndFit() on a panel usually makes no sense, is because the panel is normally part of a sizer hierarchy, and the sizers will calculate the minimum sizes of all controls recursively anyway.
Use the source, Luke!
Post Reply