void wxBitmapButton::DrawButtonDisable( WXHDC dc, int left, int top, int right, int bottom, bool with_marg ) { if ( !m_brushDisabled.Ok() ) { // draw a bitmap with two black and two background colour pixels wxBitmap bmp(2, 2); wxMemoryDC dc; dc.SelectObject(bmp); dc.SetPen(*wxBLACK_PEN); dc.DrawPoint(0, 0); dc.DrawPoint(1, 1); dc.SetPen(GetBackgroundColour()); dc.DrawPoint(0, 1); dc.DrawPoint(1, 0); m_brushDisabled = wxBrush(bmp); } SelectInHDC selectBrush((HDC)dc, GetHbrushOf(m_brushDisabled)); // ROP for "dest |= pattern" operation -- as it doesn't have a standard // name, give it our own static const DWORD PATTERNPAINT = 0xFA0089UL; if ( with_marg ) { left += m_marginX; top += m_marginY; right -= 2 * m_marginX; bottom -= 2 * m_marginY; } ::PatBlt( (HDC) dc, left, top, right, bottom, PATTERNPAINT); }
void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(this); wxMemoryDC memdc; RECT rc; ::GetClientRect(GetHwnd(), &rc); wxBitmap bmp(rc.right, rc.bottom); memdc.SelectObject(bmp); const wxLayoutDirection dir = dc.GetLayoutDirection(); memdc.SetLayoutDirection(dir); const HDC hdc = GetHdcOf(memdc); // The drawing logic of the native tab control is absolutely impenetrable // but observation shows that in the current Windows versions (XP and 7), // the tab control always erases its entire background in its window proc // when the tabs are top-aligned but does not do it when the tabs are in // any other position. // // This means that we can't rely on our background colour being used for // the blank area in the tab row because this doesn't work in the default // top-aligned case, hence the hack with ExtFloodFill() below. But it also // means that we still do need to erase the DC to account for the other // cases. // // Moreover, just in case some very old or very new (or even future, // although it seems unlikely that this is ever going to change by now) // version of Windows didn't do it like this, do both things in all cases // instead of optimizing away the one of them which doesn't do anything for // the effectively used tab orientation -- better safe than fast. // Notice that we use our own background here, not the background used for // the pages, because the tab row background must blend with the parent and // so the background colour inherited from it (if any) must be used. AutoHBRUSH hbr(wxColourToRGB(GetBackgroundColour())); ::FillRect(hdc, &rc, hbr); MSWDefWindowProc(WM_PAINT, (WPARAM)hdc, 0); // At least for the top-aligned tabs, our background colour was overwritten // and so we now replace the default background with our colour. This is // horribly inefficient, of course, but seems to be the only way to do it. if ( UseBgCol() ) { SelectInHDC selectBrush(hdc, hbr); // Find the point which must contain the default background colour: // this is a hack, of course, but using this point "close" to the // corner seems to work fine in practice. int x = 0, y = 0; switch ( GetWindowStyle() & wxBK_ALIGN_MASK ) { case wxBK_TOP: x = rc.right - 2; y = 2; break; case wxBK_BOTTOM: x = rc.right - 2; y = rc.bottom - 2; break; case wxBK_LEFT: x = 2; y = rc.bottom - 2; break; case wxBK_RIGHT: x = 2; y = rc.bottom - 2; break; } ::ExtFloodFill(hdc, x, y, ::GetSysColor(COLOR_BTNFACE), FLOODFILLSURFACE); } // For some reason in RTL mode, source offset has to be -1, otherwise the // right border (physical) remains unpainted. const wxCoord ofs = dir == wxLayout_RightToLeft ? -1 : 0; dc.Blit(ofs, 0, rc.right, rc.bottom, &memdc, ofs, 0); }