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
This commit is contained in:
Vadim Zeitlin 2011-03-22 15:07:20 +00:00
parent 4c51a665c6
commit a3b89fa936
2 changed files with 33 additions and 1 deletions

View File

@ -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

View File

@ -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;