From: Vadim Zeitlin Date: Sun, 19 Dec 2004 22:08:47 +0000 (+0000) Subject: use DeferWindowPos() instead of MoveWindow() if possible; always use WS_CLIPCHILDREN... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/9b6ae4506e8279a5ae5d00972aa494a32f64bec0 use DeferWindowPos() instead of MoveWindow() if possible; always use WS_CLIPCHILDREN; never use WS_CLIPSIBLINGS git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31076 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index a4ce110bc6..d2dd37300d 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -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; diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 554055c246..afd85c77ac 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -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: