Compiled application
I want to make the Hello World text bigger, but i can't figure out how
I tried using staticText1->SetSize(32), staticText1->SetSize(wxSize(32,32)) and replacing wxDefaultSize with wxSize(32, 32), but nothing works (I am not getting errors, it just doesnt change the text size)
This is my current code:
#include <wx/wx.h>
class Frame : public wxFrame
{
private:
wxStaticText* staticText1 = new wxStaticText(this, wxID_ANY, "Hello, World!", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
public:
Frame() : wxFrame(nullptr, wxID_ANY, "spageta", wxDefaultPosition, wxSize(400, 200)) {
staticText1->SetForegroundColour(wxTheColourDatabase->Find("Black"));
}
};
class App : public wxApp
{
public:
App();
private:
wxFrame* NewFrame = nullptr;
public:
virtual bool OnInit();
};
App::App()
{
}
bool App::OnInit()
{
NewFrame = new Frame();
NewFrame->Show(true);
return true;
}
wxIMPLEMENT_APP(App);
You need to change the font size and not the window size. The best way to do it is to change the size of the same font it already uses, e.g. window->SetFont(window->GetFont().Scale(1.5)), which would make the font 1.5 times bigger. The same approach can be used to make it bold, or italic etc.
Related
I have made an application using wxWidgets 3.1.5 in C++ and everything is working fine except a test button that I have on my main window.
Here's a pic:
The menubar, menus and their functions work perfectly but the button covers the entire client area.
Here's the code:
main.h
#pragma once
#include <wx\wx.h>
#include "mainFrame.h"
class main : public wxApp
{
private:
mainFrame* frame;
public:
virtual bool OnInit();
};
main.cpp
#include "main.h"
wxIMPLEMENT_APP(main);
bool main::OnInit()
{
frame = new mainFrame("Kill Me", wxPoint(15, 10), wxSize(640, 480));
frame->Show();
return true;
}
mainFrame.h
#pragma once
#include "About.h"
using str = std::string;
class mainFrame : public wxFrame
{
public:
mainFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
~mainFrame();
private:
About* abtF = NULL;
wxButton* hewwo = NULL;
wxMenuBar* mbar = NULL;
wxMenu* sett = NULL;
wxMenu* quitApp = NULL;
wxMenu* abt = NULL;
void onHewwo(wxCommandEvent& evt);
void onSett(wxCommandEvent& evt);
void quit(wxCommandEvent& evt);
void about(wxCommandEvent& evt);
wxDECLARE_EVENT_TABLE();
};
enum {
ID_SETT = 1,
ID_BTN = 2
};
mainFrame.cpp
#include "mainFrame.h"
wxBEGIN_EVENT_TABLE(mainFrame, wxFrame)
EVT_BUTTON(ID_BTN, onHewwo)
EVT_MENU(ID_SETT, onSett)
EVT_MENU(wxID_EXIT, quit)
EVT_MENU(wxID_ABOUT, about)
wxEND_EVENT_TABLE()
mainFrame::mainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
:
wxFrame(nullptr, wxID_ANY, title, pos, size) {
hewwo = new wxButton(this, ID_BTN, "Hewwo World", wxPoint(15, 15), wxSize(70, 20));
sett = new wxMenu();
sett->AppendSeparator();
sett->Append(ID_SETT, "&Settings");
quitApp = new wxMenu();
quitApp->AppendSeparator();
quitApp->Append(wxID_EXIT, "&Quit this crap");
abt = new wxMenu();
abt->AppendSeparator();
abt->Append(wxID_ABOUT, "&About");
mbar = new wxMenuBar();
mbar->Append(sett, "&Settings");
mbar->Append(abt, "&About");
mbar->Append(quitApp, "&Quit");
SetMenuBar(mbar);
}
void mainFrame::onHewwo(wxCommandEvent& evt) {
wxMessageBox("Hewwo", "Hewwo", wxOK | wxICON_INFORMATION, this);
}
void mainFrame::onSett(wxCommandEvent& evt) {
wxMessageBox("Settings", "Settings", wxOK | wxICON_INFORMATION, this); // Just a test
}
void mainFrame::about(wxCommandEvent& evt) {
abtF = new About(wxPoint(10, 10), wxSize(480, 320));
abtF->Show();
}
void mainFrame::quit(wxCommandEvent& evt) {
Close(true);
}
mainFrame::~mainFrame() {
delete abtF;
}
I'm using Visual Studio 2019.
(I followed OneLoneCoder's (javidx9) youtube video on wxWidgets)
That is how a wxFrame with only one child behaves.
If you don't want that, use a wxSizer to layout your button (position, align, expand etc).
Reference:
if the frame has exactly one child window, not counting the status and toolbar, this child is resized to take the entire frame client area. If two or more windows are present, they should be laid out explicitly either by manually handling wxEVT_SIZE or using sizers
wxFrame docs -> Default event processing -> wxEVT_SIZE
Hi i am trying to create a wxApp that will have not have a titlebar(including the minimize, maximize and close) icons that are by default provided. The code that i have is as follows:
main.h
class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
main.cpp
bool MyApp::OnInit()
{
MyFrame *prop = new MyFrame(wxT("MyFrame"));
prop->Show(true);
return true;
}
myframe.h
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title);
void OnClick(wxMouseEvent& event);
};
myframe.cpp
MyFrame::MyFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 130))
{
MyPanel *panel = new MyPanel(this, wxID_ANY);
panel->SetBackgroundColour(wxColour(255,255,255));
MyButton *button = new MyButton(panel, wxID_ANY, wxT("Ok"));
Connect( wxEVT_LEFT_UP,
wxMouseEventHandler(MyFrame::OnClick));
panel->Centre();
}
void MyFrame::OnClick(wxMouseEvent& event)
{
std::cout << "event reached frame class" << std::endl;
}
mypanel.h
class MyPanel : public wxPanel
{
public:
MyPanel(wxFrame *frame, int id);
void OnClick(wxMouseEvent& event);
};
mypanel.cpp
MyPanel::MyPanel(wxFrame *frame, int id)
: wxPanel(frame, id)
{
Connect( wxEVT_LEFT_UP,
wxMouseEventHandler(MyPanel::OnClick));
}
void MyPanel::OnClick(wxMouseEvent& event)
{
std::cout << "event reached panel class" << std::endl;
}
mybutton.h
class MyButton : public wxPanel
{
public:
MyButton(wxPanel *panel, int id, const wxString &label);
void OnClick(wxMouseEvent& event);
};
mybutton.cpp
void MyButton::onClick(wxMouseEvent &event)
{
}
What i want is:
There should be no title bar(including the 3 maximize, minimize & close buttons) at the top.
Now since there is no titlebar at the top of the frame, there is no way to drag or close or maximize or minimize the window. For that i want to create a custom titlebar at the top which should have the three customized maximized,minimized and close button and also i should be able to drag the frame by double clicking and holding and dragging the topmost part of the newly created frame.
Is this possible in wxWidgets? If yes, how can i achieve this?
I am not proposing any new way of dragging. The new frame/window that we will have should also be dragged only by its own customized title bar. It's exactly like dragging the old frame by double clicking and dragging the frame in the native case. I just want to customize the native title bar. Like increase its height, change it's colour, change how to three buttons(minimize, maximize and close) look.
Here's the simplest example I can think of how to create a frame with a pseudo titlebar that can be clicked to drag the frame around. This example shows which mouse events need to be handled to drag the window around and how to do the calculations needed in those event handlers.
Note that moving the frame needs to be done in screen coordinates, but the coordinates received in the event handlers will be in client coordinates for the title bar. This example also shows how to do those coordinate conversions.
#include "wx/wx.h"
class CustomTitleBar:public wxWindow
{
public:
CustomTitleBar(wxWindow* p) : wxWindow(p,wxID_ANY)
{
m_dragging = false;
SetBackgroundColour(*wxGREEN);
Bind(wxEVT_LEFT_DOWN,&CustomTitleBar::OnMouseLeftDown,this);
Bind(wxEVT_MOUSE_CAPTURE_LOST, &CustomTitleBar::OnMouseCaptureLost,
this);
}
wxSize DoGetBestClientSize() const override
{
return wxSize(-1,20);
}
private:
void OnMouseLeftDown(wxMouseEvent& event)
{
if ( !m_dragging )
{
Bind(wxEVT_LEFT_UP,&CustomTitleBar::OnMouseLeftUp,this);
Bind(wxEVT_MOTION,&CustomTitleBar::OnMouseMotion,this);
m_dragging = true;
wxPoint clientStart = event.GetPosition();
m_dragStartMouse = ClientToScreen(clientStart);
m_dragStartWindow = GetParent()->GetPosition();
CaptureMouse();
}
}
void OnMouseLeftUp(wxMouseEvent&)
{
FinishDrag();
}
void OnMouseMotion(wxMouseEvent& event)
{
wxPoint curClientPsn = event.GetPosition();
wxPoint curScreenPsn = ClientToScreen(curClientPsn);
wxPoint movementVector = curScreenPsn - m_dragStartMouse;
GetParent()->SetPosition(m_dragStartWindow + movementVector);
}
void OnMouseCaptureLost(wxMouseCaptureLostEvent&)
{
FinishDrag();
}
void FinishDrag()
{
if ( m_dragging )
{
Unbind(wxEVT_LEFT_UP,&CustomTitleBar::OnMouseLeftUp,this);
Unbind(wxEVT_MOTION,&CustomTitleBar::OnMouseMotion,this);
m_dragging = false;
}
if ( HasCapture() )
{
ReleaseMouse();
}
}
wxPoint m_dragStartMouse;
wxPoint m_dragStartWindow;
bool m_dragging;
};
class Customframe : public wxFrame
{
public:
Customframe(wxWindow* p)
:wxFrame(p, wxID_ANY, wxString(), wxDefaultPosition, wxSize(150,100),
wxBORDER_NONE)
{
CustomTitleBar* t = new CustomTitleBar(this);
SetBackgroundColour(*wxBLUE);
wxBoxSizer* szr = new wxBoxSizer(wxVERTICAL);
szr->Add(t,wxSizerFlags(0).Expand());
SetSizer(szr);
Layout();
}
};
class MyFrame: public wxFrame
{
public:
MyFrame():wxFrame(NULL, wxID_ANY, "Custom frame Demo", wxDefaultPosition,
wxSize(400, 300))
{
wxPanel* bg = new wxPanel(this, wxID_ANY);
wxButton* btn = new wxButton(bg, wxID_ANY, "Custom frame");
wxBoxSizer* szr = new wxBoxSizer(wxVERTICAL);
szr->Add(btn,wxSizerFlags(0).Border(wxALL));
bg->SetSizer(szr);
Layout();
btn->Bind(wxEVT_BUTTON, &MyFrame::OnButton, this);
m_customFrame = NULL;
}
private:
void OnButton(wxCommandEvent&)
{
if ( m_customFrame )
{
m_customFrame->Close();
m_customFrame = NULL;
}
else
{
m_customFrame = new Customframe(this);
m_customFrame->CenterOnParent();
m_customFrame->Show();
}
}
wxFrame* m_customFrame;
};
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MyFrame* frame = new MyFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
On windows, it looks like this.
You should be able to add whatever buttons you want to the custom title bar exactly as you would add buttons to any other window.
"Is this possible in wxWidgets?"
Yes. You need to use a wxWindow instead of a wxFrame and set some style for it. like wxBORDER_NONE. But you will have to implement many things that wxFrame already provides.
And your proposed way of dragging seems wrong/confusing to me. 99.99% of users prefer a UI they are used to it, avoiding to learn a new way of doing simple things they already know.
If you just want to avoid resizing then you have two ways:
a) Catch the size-event and do nothing. Calling event.Skip(false)
(to prevent handling in parent) is not neccessary.
b) Once you have created your window and correctly sized, get its size and set it as max and min.
In both cases the user will see a "resize" mouse pointer when hovering the mouse at any border, but nothing else, no resizing, will be done.
#JasonLiam,
Don't forget to place the application icon in the top left corner of you title bar and handle the right/left mouse clicks appropriately (as in native application) (if you want to go this route and get rid of the native frame window).
Thank you.
how to show another frame after button click event?
like this
My code here show window OnInit. but what to do next?
I did not find how to do this. little experience with this.
I comment the window that should be.
enum
{
wxID_First_Load = 5000,
wxID_First_Frame,
wxID_First_Panel
};
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
void fileLoad(wxCommandEvent& event);
private:
int file_count = 0;
wxDECLARE_EVENT_TABLE();
};
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(wxID_First_Load, MyFrame::fileLoad)
wxEND_EVENT_TABLE()
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame("Hello World", wxDefaultPosition, wxSize(450, 250));
frame->SetWindowStyle(wxCAPTION | wxSYSTEM_MENU );
frame->Show(true);
return true;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, wxID_First_Frame, title, pos, size)
{
wxBoxSizer *first_sizer = new wxBoxSizer(wxVERTICAL);
wxPanel *firstPanel = new wxPanel(this, wxID_First_Panel);
wxButton *firstButton_Load = new wxButton(firstPanel, wxID_First_Load, "Choose file");
firstPanel->SetSizer(first_sizer);
first_sizer->Add(firstButton_Load, 1, wxEXPAND | wxALL, 10);
firstPanel->SetSizer(first_sizer);
}
void MyFrame::fileLoad(wxCommandEvent& WXUNUSED(event))
{
file_count = 2;
}
Second Frame or window:
wxPanel *firstPanel = new wxPanel(this, wxID_First_Panel);
wxBoxSizer *second_sizer = new wxBoxSizer(wxVERTICAL);
for (int i = 0; i < file_count; i++)
{
second_sizer->Add(new wxTextCtrl(firstPanel, wxWindowID(i), "Hello", wxDefaultPosition, wxSize(235, 60)), wxSizerFlags(0).Border(wxALL, 5));
}
firstPanel->SetSizer(second_sizer);
To create a new frame you need to create a new object of wxFrame class or a class deriving from it. Typically, you want to put some data and logic into your new frame, so you would create some class, e.g. MySecondaryFrame (but hopefully with a better name) , inheriting from wxFrame in a similar way to your existing MyFrame class.
Then to show it you would do the same thing that you do in MyApp::OnInit(), i.e. create a new object of this class and call Show() to actually show it.
P.S. Note that your SetWindowStyle(wxCAPTION | wxSYSTEM_MENU ) call is unnecessary, these styles are already on by default. Also, hard coding the frame size in pixels is a bad idea, consider using sizers to determine the best size suitable for the frame contents or just leave it unspecified if it really doesn't matter.
I am trying to learn WxWidgets with C++ (I am very new at this), and I have created a window with a black background color and has a big red "X" on it. I have to edit the code so that the "X" changes its size with the window as I am resizing the window. How can I properly implement the resize event handler to this code?
Here's a screenshot of what my code produces: https://imgur.com/a/0I8EG5y
Here's what I have so far"
#include <wx/wx.h>
#include <wx/dcbuffer.h>
class MyCanvas : public wxWindow
{
public:
MyCanvas(wxWindow* parent)
: wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
{
SetBackgroundStyle(wxBG_STYLE_PAINT);
Bind(wxEVT_PAINT, &MyCanvas::OnPaint, this);
}
private:
void OnPaint(wxPaintEvent&)
{
wxAutoBufferedPaintDC dc(this);
dc.SetPen(*wxRED_PEN);
dc.SetBrush(*wxBLACK_BRUSH);
dc.DrawLine(0,0,485,485);
dc.DrawLine(0, 485, 485, 0);
}
};
class MyFrame : public wxFrame
{
public:
MyFrame()
: wxFrame(NULL, wxID_ANY, _("Resizable X"), wxDefaultPosition, wxSize(500, 525))
{
wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);
bSizer->Add(new MyCanvas(this), 1, wxEXPAND);
SetSizer(bSizer);
}
};
/**** MyApp ****/
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MyFrame* frame = new MyFrame();
frame->Show();
return true;
}
};
IMPLEMENT_APP(MyApp)
The simplest way to implement your resize handler is to do the following in MyCanvas ctor:
Bind(wxEVT_SIZE, [this](wxSizeEvent& event) { Refresh(); event.Skip(); });
This will fully refresh your canvas every time it is resized, i.e. will generate a wxEVT_PAINT that will result in a call to your existing OnPaint() handler.
Of course, for this to be actually useful, your OnPaint() should take the current window size into account, i.e. use GetClientSize() instead of hardcoded 485.
I want to view an image in one of wxSplitterWindow using wxScrolledWindow.
I derived class from wxPanel, which I add into wxScrolledWindow. But the result is not what i want.(
class ImagePanel : public wxPanel
{
public:
//ImagePanel(wxFrame* parent);
ImagePanel(wxWindow* parent);
void paintEvent(wxPaintEvent& event);
void paintNow();
void setBitmap(wxBitmap& imBitmap);
void setBitmap(wxImage& img);
int GetHeight();
int GetWidth();
void render(wxDC& dc);
DECLARE_EVENT_TABLE()
private:
wxBitmap curBitmap;
};
Paint event:
void ImagePanel::paintEvent(wxPaintEvent& event)
{
wxBufferedPaintDC dc(this);
render(dc);
}
This is how I have written the interface into main frame constructor:
topSizer = new wxBoxSizer(wxVERTICAL);
topSplitter = new wxSplitterWindow(this,ID_TOPSPLITTER,wxDefaultPosition,wxDefaultSize,wxSP_LIVE_UPDATE|wxSP_3D);
topSizer->Add(topSplitter,1,wxALL|wxEXPAND,0);
imagePanel = new wxPanel(topSplitter,ID_IMAGEPANEL);
imageSizer = new wxBoxSizer(wxVERTICAL);
imagePanel->SetSizer(imageSizer);
optionPanel = new wxPanel(topSplitter,ID_OPTIONPANEL);
optionSizer = new wxBoxSizer(wxVERTICAL);
optionPanel->SetSizer(optionSizer);
topSplitter->SplitVertically(imagePanel, optionPanel);
topSplitter->SetMinimumPaneSize(200);
//===========================================
//image panel interface
imageScWindow=new wxScrolledWindow(imagePanel,ID_IMAGESCWINDOW,wxDefaultPosition,wxDefaultSize,
wxVSCROLL|wxHSCROLL|wxALL|wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE);
imgArea = new ImagePanel(imageScWindow);
imageSizer->Add(imageScWindow,1,wxEXPAND,0);
scrollSizer = new wxBoxSizer(wxVERTICAL);
imageScWindow->SetSizer(scrollSizer);
scrollSizer->Add(imgArea,1,wxEXPAND,0);
imageScWindow->SetTargetWindow(imgArea);
And this is the function that loads image:
void MainFrame::Setpic(wxCommandEvent& event)
{
wxString path = GetCurrentWorkingDir()+wxT("\\")+tmptxt1->GetValue();
wxImage img(path);
wxBitmap imBitmap(img,-1);
imgArea->setBitmap(imBitmap);
imageScWindow->SetScrollbars(1,1,imgArea->GetWidth(),imgArea->GetHeight());
imageScWindow->Refresh();
}
Thats what i get:
https://i.imgur.com/x1GIlrl.png
I have also tried to do like this in the constructor, without SetTargetArea:
//===========================================
//image panel interface
imageScWindow=new wxScrolledWindow(imagePanel,ID_IMAGESCWINDOW,wxDefaultPosition,wxDefaultSize,
wxVSCROLL|wxHSCROLL|wxALL|wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE);
imgArea = new ImagePanel(imageScWindow);
imageSizer->Add(imageScWindow,1,wxEXPAND,0);
scrollSizer = new wxBoxSizer(wxVERTICAL);
imageScWindow->SetSizer(scrollSizer);
scrollSizer->Add(imgArea,1,wxEXPAND,0);
Then image shows properly, but if I change the frame size or move splitter, scrollbars disappear, and I have to set them again somwhere.
Then i tried to do like this:
int prvx,prvy;
void ImagePanel::paintEvent(wxPaintEvent& event)
{
reinterpret_cast<wxScrolledWindow*>(this->GetParent())->GetViewStart(&prvx,&prvy);
reinterpret_cast<wxScrolledWindow*>(this->GetParent())->SetScrollbars(1,1,curBitmap.GetWidth(),curBitmap.GetHeight());
reinterpret_cast<wxScrolledWindow*>(this->GetParent())->Scroll(wxPoint(prvx,prvy));
wxBufferedPaintDC dc(this);
render(dc);
}
It shows properly, but lags while scrolling, even without wxFULL_REPAINT_ON_RESIZE in wxScrolledWindow. The reason why it is in paint event: if I add this into OnSize event, program crashes. What to do?
I'm not sure where to begin answering your question. Here's a minimal sample of a frame that has a splitter with a bitmap on the left and a panel on the right. I hope you can adapt this sample to do what you need.
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/scrolwin.h>
#include <wx/splitter.h>
#include <wx/dcbuffer.h>
class MyFrame : public wxFrame
{
public:
MyFrame( wxWindow* parent, int id = wxID_ANY, wxString title = "Demo",
wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize,
int style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
private:
void OnScrollPaint( wxPaintEvent& event );
wxScrolledCanvas* m_canvas;
wxBitmap m_bitmap;
};
MyFrame::MyFrame( wxWindow* parent, int id, wxString title, wxPoint pos,
wxSize size, int style )
:wxFrame( parent, id, title, pos, size, style )
{
m_bitmap=wxBitmap ("test.png", wxBITMAP_TYPE_PNG );
wxSplitterWindow* m_splitter1
= new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition,
wxDefaultSize, wxSP_LIVE_UPDATE );
m_canvas = new wxScrolledCanvas( m_splitter1, wxID_ANY, wxDefaultPosition,
wxDefaultSize, wxSTATIC_BORDER|wxHSCROLL|wxVSCROLL );
m_canvas->SetScrollRate( 5, 5 );
m_canvas->SetVirtualSize(m_bitmap.GetWidth(), m_bitmap.GetHeight());
m_canvas->SetBackgroundStyle(wxBG_STYLE_PAINT);
m_canvas->Bind( wxEVT_PAINT, &MyFrame::OnScrollPaint , this );
wxPanel* m_panel2 = new wxPanel( m_splitter1, wxID_ANY, wxDefaultPosition,
wxDefaultSize, wxSTATIC_BORDER|wxTAB_TRAVERSAL );
m_splitter1->SplitVertically( m_canvas, m_panel2, GetSize().x/2 );
}
void MyFrame::OnScrollPaint( wxPaintEvent& event )
{
wxAutoBufferedPaintDC dc(m_canvas);
m_canvas->DoPrepareDC(dc);
dc.Clear();
dc.DrawBitmap(m_bitmap,0,0);
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
wxInitAllImageHandlers();
MyFrame* frame = new MyFrame(NULL);
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
To run this, be sure to change "test.png" in line 35 to the name of an actual image file on your computer (and change wxBITMAP_TYPE_PNG if the image file isn't a png).
The important parts are:
Set the background style of the canvas to wxBG_STYLE_PAINT as shown in line 46.
In the paint handler, call the DoPrepareDC method on the paintdc.
By the way, the paint handler shown in my sample isn't very good. It draws the entire bitmap every time. A better approach would be to get the update region and only redraw the parts that are needed, but I wanted to keep this simple.