I want to write an application, which must have the same appearance on any platform. I decide use wxWidgets
(I never have a large amount of work with this library).
Start my customization from ScrollBar. This was a bad decision,
(inheritance from wxScrollBar = because all control badly flickering)
because under OS Windows default ScrollBar has very poor ability for customization, explanation here. Next my step was to make same work as in this post, but use wxWidgets instead MFC.
I chose first:
#include "wx/wx.h"
#include "wx/sizer.h"
#define ENABLE_ERASING 0
#define DISABLE_BORDER 1
#define UPDATE_ON_RESIZE 0
#if DISABLE_BORDER
long gBorder = wxBORDER_NONE;
#else
long gBorder = 0;
#endif
class ScrollBar : public wxControl
{
public:
ScrollBar(wxWindow *parent, wxWindowID id);
protected:
void on_paint(wxPaintEvent& ev);
#if ENABLE_ERASING
void on_erace(wxEraseEvent& ev);
#endif
void draw(wxDC& dc);
wxSize DoGetBestSize() const override;
#if UPDATE_ON_RESIZE
void on_size(wxSizeEvent& ev);
#endif
wxDECLARE_EVENT_TABLE();
private:
};
wxBEGIN_EVENT_TABLE(ScrollBar, wxControl)
EVT_PAINT(ScrollBar::on_paint)
#if ENABLE_ERASING
EVT_ERASE_BACKGROUND(ScrollBar::on_erace)
#endif
#if UPDATE_ON_RESIZE
EVT_SIZE(ScrollBar::on_size)
#endif
wxEND_EVENT_TABLE()
ScrollBar::ScrollBar(wxWindow* parent, wxWindowID id)
: wxControl(parent, id, wxDefaultPosition, wxDefaultSize, gBorder)
{}
void ScrollBar::on_paint(wxPaintEvent& ev)
{
wxPaintDC dc(this);
draw(dc);
wxSize size = GetClientSize();
wxString text = wxString::Format("%i; %i paint", size.GetWidth(),
size.GetHeight());
dc.DrawText(text, wxPoint(74, 8));
}
#if ENABLE_ERASING
void ScrollBar::on_erace(wxEraseEvent& ev)
{
wxClientDC* clientDC = nullptr;
if (!ev.GetDC())
clientDC = new wxClientDC(this);
wxDC* dc = clientDC ? clientDC : ev.GetDC() ;
draw(*dc);
wxSize size = GetClientSize();
wxString text = wxString::Format("%i; %i erase", size.GetWidth(),
size.GetHeight());
dc->DrawText(text, wxPoint(74, 8));
if (clientDC)
delete clientDC;
}
#endif
void ScrollBar::draw(wxDC& dc)
{
wxSize size = dc.GetSize();
// draw scroll arrows
dc.SetBrush(*wxBLUE_BRUSH);
dc.SetPen( wxPen( wxColor(0,175,175), 2 ) );
dc.DrawRectangle(0, 0, 20, size.GetHeight());
dc.DrawRectangle(size.GetWidth() - 21, 0, 20, size.GetHeight());
// draw background
dc.SetBrush(*wxGREY_BRUSH);
dc.SetPen( wxPen( wxColor(175,175, 0), 2 ) );
dc.DrawRectangle(21, 0, size.GetWidth() - 43, size.GetHeight());
// draw thumb slider
dc.SetBrush(*wxCYAN_BRUSH);
dc.SetPen( wxPen( wxColor(175, 0, 175), 2 ) );
dc.DrawRectangle(70, 7, 150, 20);
dc.SetPen(wxNullPen);
dc.SetBrush(wxNullBrush);
}
wxSize ScrollBar::DoGetBestSize() const
{
return wxSize(-1, 35);
}
#if UPDATE_ON_RESIZE
void ScrollBar::on_size(wxSizeEvent& ev)
{
Refresh();
ev.Skip();
}
#endif
// ********************************************** //
class MyApp: public wxApp
{
wxFrame* frame_;
ScrollBar* sc_bar_;
public:
bool OnInit()
{
if ( !wxApp::OnInit() )
return false;
frame_ = new wxFrame(nullptr, wxID_ANY, "ScBar test App");
sc_bar_ = new ScrollBar(frame_, wxID_ANY);
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(new wxButton(frame_, -1, "Tiny Button"), 0, 0, 0);
sizer->Add(sc_bar_, 0, wxEXPAND, 0);
frame_->SetSizer(sizer);
frame_->Show();
return true;
}
};
IMPLEMENT_APP(MyApp)
And then the flicker wars began. Erasing background not help at all:
#define ENABLE_ERASING 1
Here i find solution need add correct handler for resizing:
#define ENABLE_ERASING 0
#define UPDATE_ON_RESIZE 1
OS Window 7 x64; MinGW 4.8.1; wxWidgets 3.1.0
wxWidgets is emphatically not a good choice for writing an application that must have the same appearance under all platforms because this goes straight against wxWidgets design goals which are to be indistinguishable from the native look and feel under each platform.
The only way to use wxWidgets to do what you want to is to use its wxUniversal port which does implement the same appearance everywhere. Be warned though, that it has a number of bugs and missing features compared to the usual ports (wxMSW, wxGTK, wxOSX), so you should be ready to deal with them if you decide to use it. But it would still be a much better idea than using any native port as you're apparently trying to do.