From 5fff51b517d5d237d7cc155cc94526989518263d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 15 Sep 2013 00:14:56 +0000 Subject: [PATCH] Fix flickering of wxStaticBox background in wxMSW. First of all, don't erase background in WM_ERASEBKGND at all if we erase it anyhow in WM_PAINT, this is totally useless and is what wxBG_STYLE_PAINT is for. Second, clip out not only the siblings of the static box but also its children when erasing the background to avoid painting over the controls created as the box children, which is the preferred way to create them now. Closes #15150. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74811 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/statbox.cpp | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/msw/statbox.cpp b/src/msw/statbox.cpp index da42478..678a259 100644 --- a/src/msw/statbox.cpp +++ b/src/msw/statbox.cpp @@ -81,7 +81,13 @@ bool wxStaticBox::Create(wxWindow *parent, #ifndef __WXWINCE__ if (!wxSystemOptions::IsFalse(wxT("msw.staticbox.optimized-paint"))) + { Connect(wxEVT_PAINT, wxPaintEventHandler(wxStaticBox::OnPaint)); + + // Our OnPaint() completely erases our background, so don't do it in + // WM_ERASEBKGND too to avoid flicker. + SetBackgroundStyle(wxBG_STYLE_PAINT); + } #endif // !__WXWINCE__ return true; @@ -278,8 +284,14 @@ WXHRGN wxStaticBox::MSWGetRegionWithoutChildren() HRGN hrgn = ::CreateRectRgn(rc.left, rc.top, rc.right + 1, rc.bottom + 1); bool foundThis = false; - // iterate over all child windows (not just wxWindows but all windows) - for ( HWND child = ::GetWindow(GetHwndOf(GetParent()), GW_CHILD); + // Iterate over all sibling windows as in the old wxWidgets API the + // controls appearing inside the static box were created as its siblings + // and not children. This is now deprecated but should still work. + // + // Also notice that we must iterate over all windows, not just all + // wxWindows, as there may be composite windows etc. + HWND child; + for ( child = ::GetWindow(GetHwndOf(GetParent()), GW_CHILD); child; child = ::GetWindow(child, GW_HWNDNEXT) ) { @@ -331,6 +343,23 @@ WXHRGN wxStaticBox::MSWGetRegionWithoutChildren() } } + // Also iterate over all children of the static box, we need to clip them + // out as well. + for ( child = ::GetWindow(GetHwnd(), GW_CHILD); + child; + child = ::GetWindow(child, GW_HWNDNEXT) ) + { + if ( !::IsWindowVisible(child) ) + { + // if the window isn't visible then it doesn't need clipped + continue; + } + + ::GetWindowRect(child, &rc); + AutoHRGN hrgnChild(::CreateRectRgnIndirect(&rc)); + ::CombineRgn(hrgn, hrgn, hrgnChild, RGN_DIFF); + } + return (WXHRGN)hrgn; } -- 2.7.4