From a3b89fa936319c3b40aeeb7772490c18aac74380 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 22 Mar 2011 15:07:20 +0000 Subject: [PATCH] Correctly align background brush when erasing owner drawn bitmaps in wxMSW. Add a hack to work around the problem with background alignment when drawing the owner-drawn buttons in wxMSW. This fixes the alignment for any custom brushes used for background painting but doesn't help with user-defined EVT_ERASE_BACKGROUND handlers which still don't work well with the owner-drawn buttons. Unfortunately DrawThemeParentBackground() remains a mystery and I couldn't understand why not only doesn't it position the DC correctly on its own but also ignores any attempts to do it manually. This also doesn't help with the stubbornly remaining one pixel non-transparent border around non-owner-drawn buttons which I just can't get rid of. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67281 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/button.cpp | 17 +++++++++++++++++ src/msw/window.cpp | 17 ++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) 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; -- 2.45.2