]> git.saurik.com Git - wxWidgets.git/commitdiff
use DeferWindowPos() instead of MoveWindow() if possible; always use WS_CLIPCHILDREN...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 19 Dec 2004 22:08:47 +0000 (22:08 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 19 Dec 2004 22:08:47 +0000 (22:08 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31076 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/window.h
src/msw/window.cpp

index a4ce110bc61517b06b9fc6b1095a81a203336965..d2dd37300d05ef691a8b149735415cb7037f5abb 100644 (file)
@@ -422,6 +422,10 @@ protected:
     // the old window proc (we subclass all windows)
     WXFARPROC             m_oldWndProc;
 
+    // the current multi-window move structure handle, NULL if window resize is
+    // not in process
+    WXHANDLE              m_hDWP;
+
     // additional (MSW specific) flags
     bool                  m_mouseInWindow:1;
     bool                  m_lastKeydownProcessed:1;
index 554055c2469479e3f4730f9263eb2a6dc73d1c45..afd85c77ac291d8256269857f568c4ed6cdf3f3a 100644 (file)
@@ -437,6 +437,7 @@ void wxWindowMSW::Init()
     m_frozenness = 0;
 
     m_hWnd = 0;
+    m_hDWP = 0;
 
     m_xThumbSize = 0;
     m_yThumbSize = 0;
@@ -1142,11 +1143,16 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle()
     WXDWORD style = WS_CHILD;
 
-    if ( flags & wxCLIP_CHILDREN )
-        style |= WS_CLIPCHILDREN;
+    // using this flag results in very significant reduction in flicker,
+    // especially with controls inside the static boxes (as the interior of the
+    // box is not redrawn twice)
+    style |= WS_CLIPCHILDREN;
+
+    // it doesn't seem useful to use WS_CLIPSIBLINGS here as we officially
+    // don't support overlapping windows and it only makes sense for them and,
+    // presumably, gives the system some extra work (to manage more clipping
+    // regions), so avoid it alltogether
 
-    if ( flags & wxCLIP_SIBLINGS )
-        style |= WS_CLIPSIBLINGS;
 
     if ( flags & wxVSCROLL )
         style |= WS_VSCROLL;
@@ -1525,9 +1531,30 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
         width = 0;
     if (height < 0)
         height = 0;
-    if ( !::MoveWindow(GetHwnd(), x, y, width, height, IsShown() /*Repaint?*/) )
+
+    // if our parent had prepared a defer window handle for us, use it
+    HDWP hdwp = m_parent ? (HDWP)m_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
+        m_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"));
+        }
     }
 }
 
@@ -2221,11 +2248,44 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             (void)HandleDestroy();
             break;
 
+        case WM_WINDOWPOSCHANGING:
+            {
+                // 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_SIZE:
+            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+
+            if ( m_hDWP )
+            {
+                // put all child controls in place at once now
+                if ( !::EndDeferWindowPos((HDWP)m_hDWP) )
+                {
+                    wxLogLastError(_T("EndDeferWindowPos"));
+                }
+
+                m_hDWP = NULL;
+            }
+            break;
+
         case WM_MOVE:
             processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
             break;
 
 #if !defined(__WXWINCE__)
+        // TODO: move those in WM_WINDOWPOSCHANGING case above
         case WM_MOVING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2243,13 +2303,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
-#endif
 
-        case WM_SIZE:
-            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
-            break;
-
-#if !defined(__WXWINCE__)
         case WM_SIZING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2267,7 +2321,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
-#endif
+#endif // !__WXWINCE__
 
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP: