]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Warning fix and source cleaning.
[wxWidgets.git] / src / msw / window.cpp
index 1331e0e476ca2badf257fd3a8c1568e0c90285cd..706f6740bee4181ec23ac566af8f7179c5a4bb7b 100644 (file)
@@ -437,6 +437,7 @@ void wxWindowMSW::Init()
     m_frozenness = 0;
 
     m_hWnd = 0;
+    m_hDWP = 0;
 
     m_xThumbSize = 0;
     m_yThumbSize = 0;
@@ -1531,9 +1532,30 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
     if (height < 0)
         height = 0;
 
-    if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
+    // if our parent had prepared a defer window handle for us, use it
+    wxWindowMSW *parent = GetParent();
+    HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL;
+    if ( hdwp )
     {
-        wxLogLastError(wxT("MoveWindow"));
+        hdwp = ::DeferWindowPos(hdwp, GetHwnd(), NULL,
+                                x, y, width, height,
+                                SWP_NOZORDER);
+        if ( !hdwp )
+        {
+            wxLogLastError(_T("DeferWindowPos"));
+        }
+
+        // hdwp must be updated as it may have been changed
+        parent->m_hDWP = (WXHANDLE)hdwp;
+    }
+
+    // otherwise (or if deferring failed) move the window in place immediately
+    if ( !hdwp )
+    {
+        if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
+        {
+            wxLogLastError(wxT("MoveWindow"));
+        }
     }
 }
 
@@ -2240,6 +2262,49 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             (void)HandleDestroy();
             break;
 
+#ifndef __SMARTPHONE__ // or wxWinCE in general ?
+        case WM_WINDOWPOSCHANGING:
+            {
+                WINDOWPOS *wp = wx_reinterpret_cast(WINDOWPOS *, lParam);
+
+                if ( wp->flags & SWP_NOSIZE )
+                    break;
+
+                // when we resize this window, its children are probably going
+                // to be repositioned as well, prepare to use DeferWindowPos()
+                // for them
+                const int numChildren = GetChildren().GetCount();
+                if ( numChildren > 1 )
+                {
+                    m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
+                    if ( !m_hDWP )
+                    {
+                        wxLogLastError(_T("BeginDeferWindowPos"));
+                    }
+                }
+            }
+            break;
+
+        case WM_WINDOWPOSCHANGED:
+            // first let DefWindowProc() handle the message: it will generate
+            // WM_MOVE and WM_SIZE as needed
+            processed = MSWDefWindowProc(message, wParam, lParam) == 0;
+
+            // then change the positions of all child windows at once
+            if ( m_hDWP )
+            {
+                HDWP hDWP = (HDWP)m_hDWP;
+                m_hDWP = NULL;
+
+                // put all child controls in place at once now
+                if ( !::EndDeferWindowPos(hDWP) )
+                {
+                    wxLogLastError(_T("EndDeferWindowPos"));
+                }
+            }
+            break;
+#endif // __SMARTPHONE__
+
         case WM_SIZE:
             processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
             break;
@@ -4014,9 +4079,10 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 
 void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 {
-    // standard controls always erase their background themselves (although the
-    // user may try to override it in a derived class)
-    if ( IsOfStandardClass() )
+    // standard non top level controls (i.e. except the dialogs) always erase
+    // their background themselves in HandleCtlColor() or have some control-
+    // specific ways to set the colours (common controls)
+    if ( IsOfStandardClass() && !IsTopLevel() )
     {
         event.Skip();
         return;
@@ -4032,21 +4098,26 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 
 
     // do default background painting
-    wxDC& dc = *event.GetDC();
-    HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
-    if ( hBrush )
-    {
-        RECT rc;
-        ::GetClientRect(GetHwnd(), &rc);
-        ::FillRect(GetHdcOf(dc), &rc, hBrush);
-    }
-    else
+    if ( !DoEraseBackground(*event.GetDC()) )
     {
         // let the system paint the background
         event.Skip();
     }
 }
 
+bool wxWindowMSW::DoEraseBackground(wxDC& dc)
+{
+    HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
+    if ( !hBrush )
+        return false;
+
+    RECT rc;
+    ::GetClientRect(GetHwnd(), &rc);
+    ::FillRect(GetHdcOf(dc), &rc, hBrush);
+
+    return true;
+}
+
 WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child)
 {
     wxColour col = MSWGetBgColourForChild(child);
@@ -4063,9 +4134,24 @@ WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child)
 
 wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow *child)
 {
-    return m_inheritBgCol || (m_hasBgCol && child == this)
-                ? GetBackgroundColour()
-                : wxNullColour;
+    if ( m_hasBgCol )
+    {
+        // our background colour applies to:
+        //  1. this window itself, always
+        //  2. all children unless the colour is "not inheritable"
+        //  3. immediate transparent children which should show the same
+        //     background as we do, but not for transparent grandchildren
+        //     which use the background of their immediate parent instead
+        if ( m_inheritBgCol ||
+                child == this ||
+                    (child->HasTransparentBackground() &&
+                        child->GetParent() == this) )
+        {
+            return GetBackgroundColour();
+        }
+    }
+
+    return wxNullColour;
 }
 
 WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC)