Subclassing WxControl

From WxWiki
Jump to: navigation, search

Creating a new control from an existing class in wxWidgets is easy. I needed to do this as the wxStaticText control (w/wxGTK) did not allow the background color to be modified. I did a quick search for a simple example and came up blank. I had little difficulty creating the class, but I did encounter a couple minor speed bumps along the way so I thought I would share this example. I will add more comments when I get a chance.

(In DoGetBestSize(), that looks like a perfectly good way of doing it, but I don't think the casting is necessary. wxClientDC dc(this); should do the trick. -- BrianHV)

(I just wanted to point out that if you would like to make a dll of custom controls, you need to add the preprocessor defintion 'WXUSINGDLL' to your application AND your dll projects. Also, you will want to actually link to the DLL version of wxWidgets, so be sure to build it and supply the path to the DLL version when building your applicication AND your dll projects. --cyrfer)

class myStaticText : public wxControl
{
public: 
	DECLARE_DYNAMIC_CLASS(myStaticText);

	myStaticText () {}
	myStaticText (wxWindow* parent, wxWindowID id, const wxString& txt) 
		: wxControl (parent, id) { SetLabel (txt); }

	wxSize DoGetBestSize() const;
	void OnPaint(wxPaintEvent& event);
	void SetLabel( const wxString& label );

	DECLARE_EVENT_TABLE();
};

IMPLEMENT_DYNAMIC_CLASS(myStaticText,wxControl);

BEGIN_EVENT_TABLE(myStaticText, wxControl)
	EVT_PAINT(myStaticText::OnPaint)
END_EVENT_TABLE()

wxSize myStaticText::DoGetBestSize() const
{
	// Do not return any arbitrary default value...
	wxASSERT_MSG( m_widget, wxT("myStaticText::DoGetBestSize called before creation") );

	// There is probably a better way than this, but I don't know it.
	// So I use the const_cast to grab a dc that is only used for metrics.
	wxClientDC dc (const_cast<myStaticText*> (this));

	wxCoord w = 0;
	wxCoord h = 0;
	dc.GetTextExtent( GetLabel (), &w, &h );

	return wxSize( w, h );
}

void myStaticText::OnPaint(wxPaintEvent& WXUNUSED(event))
{
	wxPaintDC dc (this);
	wxCoord 
	x = 0,
	y = 0,
	width = 0,
	height = 0,
	tw = 0,
	th = 0;

	GetClientSize( &width, &height );

	dc.SetTextForeground (GetForegroundColour ());
	dc.SetTextBackground (GetBackgroundColour ());

	dc.DrawText( GetLabel (), 0, 0);
}

void myStaticText::SetLabel( const wxString& label )
{
	wxControl::SetLabel( label );
	Refresh ();
}