]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix flickering of wxStaticBox background in wxMSW.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 15 Sep 2013 00:14:56 +0000 (00:14 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 15 Sep 2013 00:14:56 +0000 (00:14 +0000)
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

index da42478341ff7fda738cd8510ae86d987e91873b..678a2594cff0245ac8310816db7a81ab8f8dc4f8 100644 (file)
@@ -81,7 +81,13 @@ bool wxStaticBox::Create(wxWindow *parent,
 
 #ifndef __WXWINCE__
     if (!wxSystemOptions::IsFalse(wxT("msw.staticbox.optimized-paint")))
 
 #ifndef __WXWINCE__
     if (!wxSystemOptions::IsFalse(wxT("msw.staticbox.optimized-paint")))
+    {
         Connect(wxEVT_PAINT, wxPaintEventHandler(wxStaticBox::OnPaint));
         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;
 #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;
 
     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) )
     {
           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;
 }
 
     return (WXHRGN)hrgn;
 }