From: Vadim Zeitlin Date: Mon, 13 Dec 2004 00:09:54 +0000 (+0000) Subject: rewrote and virtualized the background erasing logic: each window may now X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/c5bd3c6268277ae8fedddcd6ebafa8ba90f3d551 rewrote and virtualized the background erasing logic: each window may now specify which background brush should be used for its children and each child may also choose to use either background brush or (solid) background colour wxWindow::OnEraseBackground() and wxControl::MSWControlColor() now use the same code git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30976 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 27041df751..d445002683 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -364,6 +364,45 @@ public: // with or 0 for the default brush virtual WXHBRUSH MSWControlColor(WXHDC hDC); + // this function should return the brush to paint the children controls + // background or 0 if this window doesn't impose any particular background + // on its children + // + // the base class version uses MSWGetBgColourForChild() and returns a solid + // brush if we have a non default background colour or 0 otherwise + virtual WXHBRUSH MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), wxWindow *child) + { + return MSWGetSolidBgBrushForChild(child); + } + + // return the background colour of this window under the given child + // (possible grand child) + // + // this is a hack as if the background is themed, there is no single colour + // representing it, but sometimes we can't use the pattern brush returned + // by MSWGetBgBrushForChild() anyhow and then this function is used as + // fallback + // + // the base class version returns bg colour if it had been explicitely set + // or wxNullColour otherwise + virtual wxColour MSWGetBgColourForChild(wxWindow *child); + + // convenience function: returns a solid brush of the colour returned by + // MSWGetBgColourForChild() or 0 + WXHBRUSH MSWGetSolidBgBrushForChild(wxWindow *child); + + // normally just calls MSWGetBgBrushForChild() on the parent window but may + // be overridden if the default background brush is not suitable for some + // reason (e.g. wxStaticBox uses MSWGetSolidBgBrushForChild() instead) + virtual WXHBRUSH MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC) + { + return parent->MSWGetBgBrushForChild(hDC, this); + } + + // return the background brush to use for this window by quering the parent + // windows via their MSWGetBgBrushForChild() recursively + WXHBRUSH MSWGetBgBrush(WXHDC hDC); + // Responds to colour changes: passes event on to children. void OnSysColourChanged(wxSysColourChangedEvent& event); diff --git a/src/msw/control.cpp b/src/msw/control.cpp index 304829225a..fe571c7536 100644 --- a/src/msw/control.cpp +++ b/src/msw/control.cpp @@ -358,44 +358,9 @@ WXHBRUSH wxControl::MSWControlColor(WXHDC pDC) ::SetBkMode((HDC)pDC, TRANSPARENT); - // check if we should adapt our background to our parent - for ( wxWindow *win = this; win; win = win->GetParent() ) - { - if ( win->IsTopLevel() ) - { - // don't go beyond the first top level parent - break; - } - - if ( win->GetBackgroundStyle() == wxBG_STYLE_COLOUR ) - { - // parent window has solid colour, so it doesn't look - // transparent and hence we shouldn't show notebook background - wxBrush *brush = wxTheBrushList->FindOrCreateBrush - ( - win->GetBackgroundColour(), - wxSOLID - ); - - return (WXHBRUSH)brush->GetResourceHandle(); - } - -#if wxUSE_UXTHEME && wxUSE_NOTEBOOK - // check for the special case of the notebooks which draw themed - // background when themes are enabled - wxNotebook *nbook = wxDynamicCast(win, wxNotebook); - if ( nbook ) - { - // return value may be NULL but it is ok: if the first parent - // notebook doesn't use themes, then we don't have to process - // this message at all, so let default processing take place - return nbook->GetThemeBackgroundBrush(pDC, this); - } -#endif // wxUSE_UXTHEME && wxUSE_NOTEBOOK - } + hbr = MSWGetBgBrush(pDC); - // let the control deal with background itself - return MSWGetDefaultBgBrush(); + return hbr ? hbr : MSWGetDefaultBgBrush(); } WXHBRUSH wxControl::MSWControlColorDisabled(WXHDC pDC) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index a2c31ccb8f..ce28f74fa4 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3938,9 +3938,6 @@ extern wxCOLORMAP *wxGetStdColourMap() bool wxWindowMSW::HandlePaint() { -// if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND) -// return false; - HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle if ( !hRegion ) wxLogLastError(wxT("CreateRectRgn")); @@ -3980,10 +3977,6 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event) bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) { - // Prevents flicker when dragging - if ( ::IsIconic(GetHwnd()) ) - return true; - wxDCTemp dc(hdc); dc.SetHDC(hdc); @@ -4004,53 +3997,72 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) void wxWindowMSW::OnEraseBackground(wxEraseEvent& event) { - switch ( GetBackgroundStyle() ) + // standard controls always erase their background themselves (although the + // user may try to override it in a derived class) + if ( IsOfStandardClass() ) { - default: - wxFAIL_MSG( _T("unexpected background style") ); - // fall through + event.Skip(); + return; + } - case wxBG_STYLE_CUSTOM: - // don't skip the event here, custom background means that the app - // is drawing it itself in its OnPaint() - break; + if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM ) + { + // don't skip the event here, custom background means that the app + // is drawing it itself in its OnPaint(), so don't draw it at all + // now to avoid flicker + return; + } - case wxBG_STYLE_SYSTEM: -#if wxUSE_NOTEBOOK && wxUSE_UXTHEME && !defined(__WXUNIVERSAL__) - // automatically apply the tab control theme background to any - // child panels to have the same look as the native property sheet - // dialogs - if ( !IsOfStandardClass() ) - { - for ( wxWindow *win = this; win; win = win->GetParent() ) - { - wxNotebook *nbook = wxDynamicCast(win, wxNotebook); - if ( nbook ) - { - nbook->DoEraseBackground(event); - return; - } - } - } -#endif // wxUSE_NOTEBOOK - event.Skip(); - break; - case wxBG_STYLE_COLOUR: - // we have a fixed solid background colour, do use it - RECT rect; - ::GetClientRect(GetHwnd(), &rect); + // do default background painting + wxDC& dc = *event.GetDC(); + HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC()); + if ( hBrush ) + { + RECT rc; + ::GetClientRect(GetHwnd(), &rc); + ::FillRect(GetHdcOf(dc), &rc, hBrush); + } + else + { + // let the system paint the background + event.Skip(); + } +} + +WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child) +{ + wxColour col = MSWGetBgColourForChild(child); + if ( col.Ok() ) + { + // draw children with the same colour as the parent + wxBrush *brush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID); + + return (WXHBRUSH)brush->GetResourceHandle(); + } - HBRUSH hBrush = ::CreateSolidBrush( - wxColourToPalRGB(GetBackgroundColour())); - if ( !hBrush ) - wxLogLastError(wxT("CreateSolidBrush")); + return 0; +} - HDC hdc = GetHdcOf((*event.GetDC())); +wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow * WXUNUSED(child)) +{ + return m_hasBgCol ? GetBackgroundColour() : wxNullColour; +} - ::FillRect(hdc, &rect, hBrush); - ::DeleteObject(hBrush); +WXHBRUSH wxWindow::MSWGetBgBrush(WXHDC hDC) +{ + for ( wxWindow *win = this; win; win = win->GetParent() ) + { + // background is not inherited beyond the containing TLW + if ( win->IsTopLevel() ) + break; + + WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC); + if ( hBrush ) + return hBrush; } + + return 0; } // ---------------------------------------------------------------------------