From 7d86a2d45c1c08cbd64ca1f619b1adeb2c390665 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 30 Jul 2005 00:01:51 +0000 Subject: [PATCH] replaced wxMoveWindowDeferred() with wxWindow::DoMoveSibling() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@35007 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/private.h | 3 - include/wx/msw/window.h | 5 ++ src/msw/radiobox.cpp | 25 +------- src/msw/slider95.cpp | 58 ++++++----------- src/msw/spinctrl.cpp | 29 +-------- src/msw/window.cpp | 135 ++++++++++++++------------------------- 6 files changed, 75 insertions(+), 180 deletions(-) diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index f165bf13e8..840642a60c 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -818,9 +818,6 @@ inline bool wxStyleHasBorder(long style) wxSUNKEN_BORDER | wxDOUBLE_BORDER)) != 0; } -// Deferred window moving -bool wxMoveWindowDeferred(HDWP& hdwp, wxWindowBase* win, HWND hWnd, int x, int y, int width, int height); - // ---------------------------------------------------------------------------- // functions mapping HWND to wxWindow // ---------------------------------------------------------------------------- diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 39ba4694f7..d322098a87 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -455,6 +455,11 @@ protected: // has the window been frozen by Freeze()? bool IsFrozen() const { return m_frozenness > 0; } + // this simply moves/resizes the given HWND which is supposed to be our + // sibling (this is useful for controls which are composite at MSW level + // and for which DoMoveWindow() is not enough) + void DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height); + // move the window to the specified location and resize it: this is called // from both DoSetSize() and DoSetClientSize() and would usually just call // ::MoveWindow() except for composite controls which will want to arrange diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp index 09abc32319..e1b113051f 100644 --- a/src/msw/radiobox.cpp +++ b/src/msw/radiobox.cpp @@ -40,11 +40,6 @@ #include "wx/msw/subwin.h" -// This is switched off because in some situations, the radiobox -// buttons simply don't appear when deferred sizing is on. -// Instead, refreshing on WM_MOVE seems to at least cure the droppings. -#define USE_DEFERRED_SIZING 0 - #if wxUSE_TOOLTIPS #if !defined(__GNUWIN32_OLD__) || defined(__CYGWIN10__) #include @@ -557,17 +552,7 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) height = heightOld; } - // if our parent had prepared a defer window handle for us, use it (unless - // we are a top level window) - -#if USE_DEFERRED_SIZING - wxWindowMSW *parent = GetParent(); - HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL; -#else - HDWP hdwp = 0; -#endif - - wxMoveWindowDeferred(hdwp, this, GetHwnd(), xx, yy, width, height); + DoMoveWindow(xx, yy, width, height); // Now position all the buttons: the current button will be put at // wxPoint(x_offset, y_offset) and the new row/column will start at @@ -664,14 +649,6 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags) x_offset += widthBtn + cx1; } } - -#if USE_DEFERRED_SIZING - if (parent) - { - // hdwp must be updated as it may have been changed - parent->m_hDWP = (WXHANDLE)hdwp; - } -#endif } // ---------------------------------------------------------------------------- diff --git a/src/msw/slider95.cpp b/src/msw/slider95.cpp index 479a180b82..39ee05810a 100644 --- a/src/msw/slider95.cpp +++ b/src/msw/slider95.cpp @@ -42,8 +42,6 @@ #include #endif -#define USE_DEFERRED_SIZING 1 - // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -460,16 +458,6 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height) return; } - // if our parent had prepared a defer window handle for us, use it (unless - // we are a top level window) - wxWindowMSW *parent = GetParent(); - -#if USE_DEFERRED_SIZING - HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL; -#else - HDWP hdwp = 0; -#endif - // be careful to position the slider itself after moving the labels as // otherwise our GetBoundingBox(), which is called from WM_SIZE handler, // would return a wrong result and wrong size would be cached internally @@ -482,21 +470,20 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height) // position all labels: min at the top, value in the middle and max at // the bottom - wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min], + DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min], xLabel, y, wLabel, hLabel); - wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value], + DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value], xLabel, y + (height - hLabel)/2, wLabel, hLabel); - wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max], - xLabel, y + height - hLabel, wLabel, hLabel); + DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max], + xLabel, y + height - hLabel, wLabel, hLabel); // position the slider itself along the left/right edge - wxMoveWindowDeferred(hdwp, this, GetHwnd(), - HasFlag(wxSL_LEFT) ? x : x + wLabel + HGAP, - y + hLabel/2, - width - wLabel - HGAP, - height - hLabel); + wxSliderBase::DoMoveWindow(HasFlag(wxSL_LEFT) ? x : x + wLabel + HGAP, + y + hLabel/2, + width - wLabel - HGAP, + height - hLabel); } else // horizontal { @@ -507,30 +494,21 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height) // position all labels: min on the left, value in the middle and max to // the right - wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min], - x, yLabel, wLabel, hLabel); + DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min], + x, yLabel, wLabel, hLabel); - wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value], - x + (width - wLabel)/2, yLabel, wLabel, hLabel); + DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value], + x + (width - wLabel)/2, yLabel, wLabel, hLabel); - wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max], - x + width - wLabel, yLabel, wLabel, hLabel); + DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max], + x + width - wLabel, yLabel, wLabel, hLabel); // position the slider itself along the top/bottom edge - wxMoveWindowDeferred(hdwp, this, GetHwnd(), - x, - HasFlag(wxSL_TOP) ? y : y + hLabel, - width, - height - hLabel); + wxSliderBase::DoMoveWindow(x, + HasFlag(wxSL_TOP) ? y : y + hLabel, + width, + height - hLabel); } - -#if USE_DEFERRED_SIZING - if ( parent ) - { - // hdwp must be updated as it may have been changed - parent->m_hDWP = (WXHANDLE)hdwp; - } -#endif } wxSize wxSlider::DoGetBestSize() const diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp index 39960aed32..93eeaf4a39 100644 --- a/src/msw/spinctrl.cpp +++ b/src/msw/spinctrl.cpp @@ -45,9 +45,6 @@ #include // for INT_MIN -#define USE_DEFERRED_SIZING 1 -#define USE_DEFER_BUG_WORKAROUND 0 - // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -454,7 +451,7 @@ void wxSpinCtrl::SetSelection(long from, long to) from = 0; } - ::SendMessage((HWND)m_hwndBuddy, EM_SETSEL, (WPARAM)from, (LPARAM)to); + ::SendMessage(GetBuddyHwnd(), EM_SETSEL, (WPARAM)from, (LPARAM)to); } // ---------------------------------------------------------------------------- @@ -570,32 +567,12 @@ void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height) wxLogDebug(_T("not enough space for wxSpinCtrl!")); } - // if our parent had prepared a defer window handle for us, use it (unless - // we are a top level window) - wxWindowMSW *parent = GetParent(); - -#if USE_DEFERRED_SIZING - HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL; -#else - HDWP hdwp = 0; -#endif - // 1) The buddy window - wxMoveWindowDeferred(hdwp, this, GetBuddyHwnd(), - x, y, widthText, height); + DoMoveSibling(m_hwndBuddy, x, y, widthText, height); // 2) The button window x += widthText + MARGIN_BETWEEN; - wxMoveWindowDeferred(hdwp, this, GetHwnd(), - x, y, widthBtn, height); - -#if USE_DEFERRED_SIZING - if (parent) - { - // hdwp must be updated as it may have been changed - parent->m_hDWP = (WXHANDLE)hdwp; - } -#endif + wxSpinButton::DoMoveWindow(x, y, widthBtn, height); } // get total size of the control diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 8063d16afc..8002aab371 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -121,8 +121,11 @@ #define HAVE_TRACKMOUSEEVENT #endif // everything needed for TrackMouseEvent() +// if this is set to 1, we use deferred window sizing to reduce flicker when +// resizing complicated window hierarchies, but this can in theory result in +// different behaviour than the old code so we keep the possibility to use it +// by setting this to 0 (in the future this should be removed completely) #define USE_DEFERRED_SIZING 1 -#define USE_DEFER_BUG_WORKAROUND 1 // --------------------------------------------------------------------------- // global variables @@ -1486,8 +1489,8 @@ void wxWindowMSW::DoGetPosition(int *x, int *y) const if ( parent ) hParentWnd = GetWinHwnd(parent); - // Since we now have the absolute screen coords, if there's a parent we - // must subtract its top left corner + // Since we now have the absolute screen coords, if there's a + // parent we must subtract its top left corner if ( hParentWnd ) { ::ScreenToClient(hParentWnd, &point); @@ -1495,8 +1498,8 @@ void wxWindowMSW::DoGetPosition(int *x, int *y) const if ( parent ) { - // We may be faking the client origin. So a window that's really at (0, - // 30) may appear (to wxWin apps) to be at (0, 0). + // We may be faking the client origin. So a window that's + // really at (0, 30) may appear (to wxWin apps) to be at (0, 0). wxPoint pt(parent->GetClientAreaOrigin()); point.x -= pt.x; point.y -= pt.y; @@ -1541,6 +1544,42 @@ void wxWindowMSW::DoClientToScreen(int *x, int *y) const *y = pt.y; } +void +wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height) +{ +#if USE_DEFERRED_SIZING + // if our parent had prepared a defer window handle for us, use it (unless + // we are a top level window) + wxWindowMSW * const parent = IsTopLevel() ? NULL : GetParent(); + + HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL; + if ( hdwp ) + { + hdwp = ::DeferWindowPos(hdwp, (HWND)hwnd, NULL, x, y, width, height, + SWP_NOZORDER); + if ( !hdwp ) + { + wxLogLastError(_T("DeferWindowPos")); + } + } + + if ( parent ) + { + // 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 ) +#endif // USE_DEFERRED_SIZING + { + if ( !::MoveWindow((HWND)hwnd, x, y, width, height, IsShown()) ) + { + wxLogLastError(wxT("MoveWindow")); + } + } +} + void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height) { // TODO: is this consistent with other platforms? @@ -1550,23 +1589,7 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height) if (height < 0) height = 0; - // if our parent had prepared a defer window handle for us, use it (unless - // we are a top level window) - wxWindowMSW *parent = GetParent(); - -#if USE_DEFERRED_SIZING - HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL; -#else - HDWP hdwp = 0; -#endif - - wxMoveWindowDeferred(hdwp, this, GetHwnd(), x, y, width, height); - -#if USE_DEFERRED_SIZING - if ( parent ) - // hdwp must be updated as it may have been changed - parent->m_hDWP = (WXHANDLE)hdwp; -#endif + DoMoveSibling(m_hWnd, x, y, width, height); } // set the size of the window: if the dimensions are positive, just use them, @@ -1583,26 +1606,8 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags) int currentX, currentY; int currentW, currentH; -#if USE_DEFER_BUG_WORKAROUND - currentX = m_pendingPosition.x; - if (currentX == wxDefaultCoord) - GetPosition(¤tX, NULL); - - currentY = m_pendingPosition.y; - if (currentY == wxDefaultCoord) - GetPosition(NULL, ¤tY); - - currentW = m_pendingSize.x; - if (currentW == wxDefaultCoord) - GetSize(¤tW, NULL); - - currentH = m_pendingSize.y; - if (currentH == wxDefaultCoord) - GetSize(NULL, ¤tH); -#else GetPosition(¤tX, ¤tY); GetSize(¤tW, ¤tH); -#endif // ... and don't do anything (avoiding flicker) if it's already ok if ( x == currentX && y == currentY && @@ -1652,25 +1657,8 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags) } } -#if USE_DEFER_BUG_WORKAROUND - // We don't actually use the hdwp here, but we need to know whether to - // save the pending dimensions or not. This isn't done in DoMoveWindow - // (where the hdwp is used) because some controls have thier own - // DoMoveWindow so it is easier to catch it here. - wxWindowMSW *parent = GetParent(); - HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL; - if (hdwp) - { - m_pendingPosition = wxPoint(x, y); - m_pendingSize = wxSize(width, height); - } - else - { - m_pendingPosition = wxDefaultPosition; - m_pendingSize = wxDefaultSize; - } -#endif - + m_pendingPosition = wxPoint(x, y); + m_pendingSize = wxSize(width, height); DoMoveWindow(x, y, width, height); } @@ -4251,7 +4239,6 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) wxLogLastError(_T("EndDeferWindowPos")); } -#if USE_DEFER_BUG_WORKAROUND // Reset our children's pending pos/size values. for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; @@ -4261,9 +4248,8 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) child->m_pendingPosition = wxDefaultPosition; child->m_pendingSize = wxDefaultSize; } -#endif } -#endif +#endif // USE_DEFERRED_SIZING return processed; } @@ -6000,31 +5986,6 @@ bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam) #endif // wxUSE_HOTKEY -// Moves a window by deferred method or normal method -bool wxMoveWindowDeferred(HDWP& hdwp, wxWindowBase* win, HWND hWnd, int x, int y, int width, int height) -{ - if ( hdwp ) - { - hdwp = ::DeferWindowPos(hdwp, hWnd, NULL, - x, y, width, height, - SWP_NOZORDER); - if ( !hdwp ) - { - wxLogLastError(_T("DeferWindowPos")); - } - } - - // otherwise (or if deferring failed) move the window in place immediately - if ( !hdwp ) - { - if ( !::MoveWindow(hWnd, x, y, width, height, win->IsShown()) ) - { - wxLogLastError(wxT("MoveWindow")); - } - } - return hdwp != NULL; -} - // Not tested under WinCE #ifndef __WXWINCE__