diff --git a/src/msw/button.cpp b/src/msw/button.cpp index 280947275d..d92ea4da35 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -115,6 +115,10 @@ using namespace wxMSWImpl; #define BCM_SETSHIELD 0x160c #endif +#if wxUSE_UXTHEME +extern wxWindowMSW *wxWindowBeingErased; // From src/msw/window.cpp +#endif // wxUSE_UXTHEME + // ---------------------------------------------------------------------------- // button image data // ---------------------------------------------------------------------------- @@ -1315,7 +1319,20 @@ void DrawXPBackground(wxButton *button, HDC hdc, RECT& rectBtn, UINT state) iState ) ) { + // Set this button as the one whose background is being erased: this + // allows our WM_ERASEBKGND handler used by DrawThemeParentBackground() + // to correctly align the background brush with this window instead of + // the parent window to which WM_ERASEBKGND is sent. Notice that this + // doesn't work with custom user-defined EVT_ERASE_BACKGROUND handlers + // as they won't be aligned but unfortunately all the attempts to fix + // it by shifting DC origin before calling DrawThemeParentBackground() + // failed to work so we at least do this, even though this is far from + // being the perfect solution. + wxWindowBeingErased = button; + engine->DrawThemeParentBackground(GetHwndOf(button), hdc, &rectBtn); + + wxWindowBeingErased = NULL; } // draw background diff --git a/src/msw/window.cpp b/src/msw/window.cpp index d982f3ed22..165c03c207 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -182,6 +182,13 @@ extern wxMenu *wxCurrentPopupMenu; #endif +#if wxUSE_UXTHEME +// This is a hack used by the owner-drawn wxButton implementation to ensure +// that the brush used for erasing its background is correctly aligned with the +// control. +extern wxWindowMSW *wxWindowBeingErased = NULL; +#endif // wxUSE_UXTHEME + namespace { @@ -4921,9 +4928,17 @@ wxWindowMSW::MSWGetBgBrushForChild(WXHDC hDC, wxWindowMSW *child) WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC) { + // Use the special wxWindowBeingErased variable if it is set as the child + // being erased. + wxWindowMSW * const child = +#if wxUSE_UXTHEME + wxWindowBeingErased ? wxWindowBeingErased : +#endif + this; + for ( wxWindowMSW *win = this; win; win = win->GetParent() ) { - WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, this); + WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, child); if ( hBrush ) return hBrush;