diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index 6b171c7a74..7a5bf36c59 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -254,6 +254,13 @@ bool wxNotebook::Create(wxWindow *parent, if ( !MSWCreateControl(className, wxEmptyString, pos, size) ) return false; + // Inherit parent attributes and, unlike the default, also inherit the + // parent background colour in order to blend in with its background if + // it's set to a non-default value. + InheritAttributes(); + if ( parent->InheritsBackgroundColour() && !UseBgCol() ) + SetBackgroundColour(parent->GetBackgroundColour()); + #if wxUSE_UXTHEME if ( HasFlag(wxNB_NOPAGETHEME) || wxSystemOptions::IsFalse(wxT("msw.notebook.themed-background")) ) @@ -835,25 +842,74 @@ void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event)) const wxLayoutDirection dir = dc.GetLayoutDirection(); memdc.SetLayoutDirection(dir); - // if there is no special brush just use the solid background colour -#if wxUSE_UXTHEME - HBRUSH hbr = (HBRUSH)m_hbrBackground; -#else - HBRUSH hbr = 0; -#endif - wxBrush brush; - if ( !hbr ) + 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() ) { - brush = wxBrush(GetBackgroundColour()); - hbr = GetHbrushOf(brush); + 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); } - wxMSWDCImpl *impl = (wxMSWDCImpl*) memdc.GetImpl(); - - ::FillRect(GetHdcOf(*impl), &rc, hbr); - - MSWDefWindowProc(WM_PAINT, (WPARAM)(impl->GetHDC()), 0); - // 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;