Page 1 of 1

Transparent control background on MSW.

Posted: Fri Feb 13, 2009 12:25 pm
by pete_b
Found a way to do transparent backgrounds on MSW for wxCheckBox. Presumably would work for other stuff.
Also you may need to override wxEVT_ERASE_BACKGROUND for your child controls.
The handling is done by the parent panel, which gets the WM_CTLCOLOURxxx messages.

Code: Select all

class WinDC : public wxClientDC
{
public:
	WinDC(wxWindow *canvas, WXHDC hdc)
	{
		m_canvas = canvas;
		m_hDC = hdc;
		InitDC();
	}
};

WXLRESULT 
MyPanel::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
	switch (message) {
	case WM_CTLCOLORMSGBOX:
	case WM_CTLCOLOREDIT:
	case WM_CTLCOLORLISTBOX:
	case WM_CTLCOLORBTN:
	case WM_CTLCOLORDLG:
	case WM_CTLCOLORSCROLLBAR:
	case WM_CTLCOLORSTATIC:
	{
		WXHDC wxhdc;
		WXHWND hwnd;
		UnpackCtlColor(wParam, lParam, &wxhdc, &hwnd);
		wxWindow* win = wxGetWindowFromHWND(hwnd);
		if (win) {
			::SetBkMode((HDC)wxhdc, TRANSPARENT);
			WinDC dc(win, wxhdc);
			drawCompositedBackground(dc, win);
			HBRUSH brush = (HBRUSH)GetStockObject(HOLLOW_BRUSH);
			return (WXLRESULT)brush;
		}
	}
	break;
	default:
		break;
	}
	return super::MSWWindowProc(message, wParam, lParam);
}

void 
MyPanel::drawCompositedBackground(wxDC& dc, wxWindow* window)
{
// background_ is a wxBitmap that covers the whole panel.
	wxMemoryDC mdc(background_);
	wxRect client = window->GetClientRect();
	wxPoint pos = window->GetPosition();
	dc.Blit(0, 0, client.width, client.height, &mdc, pos.x, pos.y);
}