replaced wxMoveWindowDeferred() with wxWindow::DoMoveSibling()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@35007 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2005-07-30 00:01:51 +00:00
parent 7a0e7e55d8
commit 7d86a2d45c
6 changed files with 75 additions and 180 deletions

View File

@@ -818,9 +818,6 @@ inline bool wxStyleHasBorder(long style)
wxSUNKEN_BORDER | wxDOUBLE_BORDER)) != 0; 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 // functions mapping HWND to wxWindow
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -455,6 +455,11 @@ protected:
// has the window been frozen by Freeze()? // has the window been frozen by Freeze()?
bool IsFrozen() const { return m_frozenness > 0; } 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 // move the window to the specified location and resize it: this is called
// from both DoSetSize() and DoSetClientSize() and would usually just call // from both DoSetSize() and DoSetClientSize() and would usually just call
// ::MoveWindow() except for composite controls which will want to arrange // ::MoveWindow() except for composite controls which will want to arrange

View File

@@ -40,11 +40,6 @@
#include "wx/msw/subwin.h" #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 wxUSE_TOOLTIPS
#if !defined(__GNUWIN32_OLD__) || defined(__CYGWIN10__) #if !defined(__GNUWIN32_OLD__) || defined(__CYGWIN10__)
#include <commctrl.h> #include <commctrl.h>
@@ -557,17 +552,7 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
height = heightOld; height = heightOld;
} }
// if our parent had prepared a defer window handle for us, use it (unless DoMoveWindow(xx, yy, width, height);
// 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);
// Now position all the buttons: the current button will be put at // 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 // 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; 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
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -42,8 +42,6 @@
#include <commctrl.h> #include <commctrl.h>
#endif #endif
#define USE_DEFERRED_SIZING 1
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// constants // constants
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -460,16 +458,6 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
return; 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 // be careful to position the slider itself after moving the labels as
// otherwise our GetBoundingBox(), which is called from WM_SIZE handler, // otherwise our GetBoundingBox(), which is called from WM_SIZE handler,
// would return a wrong result and wrong size would be cached internally // 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 // position all labels: min at the top, value in the middle and max at
// the bottom // the bottom
wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min], DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
xLabel, y, wLabel, hLabel); xLabel, y, wLabel, hLabel);
wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value], DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
xLabel, y + (height - hLabel)/2, wLabel, hLabel); xLabel, y + (height - hLabel)/2, wLabel, hLabel);
wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max], DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
xLabel, y + height - hLabel, wLabel, hLabel); xLabel, y + height - hLabel, wLabel, hLabel);
// position the slider itself along the left/right edge // position the slider itself along the left/right edge
wxMoveWindowDeferred(hdwp, this, GetHwnd(), wxSliderBase::DoMoveWindow(HasFlag(wxSL_LEFT) ? x : x + wLabel + HGAP,
HasFlag(wxSL_LEFT) ? x : x + wLabel + HGAP, y + hLabel/2,
y + hLabel/2, width - wLabel - HGAP,
width - wLabel - HGAP, height - hLabel);
height - hLabel);
} }
else // horizontal 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 // position all labels: min on the left, value in the middle and max to
// the right // the right
wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min], DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
x, yLabel, wLabel, hLabel); x, yLabel, wLabel, hLabel);
wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value], DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
x + (width - wLabel)/2, yLabel, wLabel, hLabel); x + (width - wLabel)/2, yLabel, wLabel, hLabel);
wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max], DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
x + width - wLabel, yLabel, wLabel, hLabel); x + width - wLabel, yLabel, wLabel, hLabel);
// position the slider itself along the top/bottom edge // position the slider itself along the top/bottom edge
wxMoveWindowDeferred(hdwp, this, GetHwnd(), wxSliderBase::DoMoveWindow(x,
x, HasFlag(wxSL_TOP) ? y : y + hLabel,
HasFlag(wxSL_TOP) ? y : y + hLabel, width,
width, height - hLabel);
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 wxSize wxSlider::DoGetBestSize() const

View File

@@ -45,9 +45,6 @@
#include <limits.h> // for INT_MIN #include <limits.h> // for INT_MIN
#define USE_DEFERRED_SIZING 1
#define USE_DEFER_BUG_WORKAROUND 0
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// macros // macros
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -454,7 +451,7 @@ void wxSpinCtrl::SetSelection(long from, long to)
from = 0; 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!")); 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 // 1) The buddy window
wxMoveWindowDeferred(hdwp, this, GetBuddyHwnd(), DoMoveSibling(m_hwndBuddy, x, y, widthText, height);
x, y, widthText, height);
// 2) The button window // 2) The button window
x += widthText + MARGIN_BETWEEN; x += widthText + MARGIN_BETWEEN;
wxMoveWindowDeferred(hdwp, this, GetHwnd(), wxSpinButton::DoMoveWindow(x, y, widthBtn, height);
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
} }
// get total size of the control // get total size of the control

View File

@@ -121,8 +121,11 @@
#define HAVE_TRACKMOUSEEVENT #define HAVE_TRACKMOUSEEVENT
#endif // everything needed for 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_DEFERRED_SIZING 1
#define USE_DEFER_BUG_WORKAROUND 1
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// global variables // global variables
@@ -1486,8 +1489,8 @@ void wxWindowMSW::DoGetPosition(int *x, int *y) const
if ( parent ) if ( parent )
hParentWnd = GetWinHwnd(parent); hParentWnd = GetWinHwnd(parent);
// Since we now have the absolute screen coords, if there's a parent we // Since we now have the absolute screen coords, if there's a
// must subtract its top left corner // parent we must subtract its top left corner
if ( hParentWnd ) if ( hParentWnd )
{ {
::ScreenToClient(hParentWnd, &point); ::ScreenToClient(hParentWnd, &point);
@@ -1495,8 +1498,8 @@ void wxWindowMSW::DoGetPosition(int *x, int *y) const
if ( parent ) if ( parent )
{ {
// We may be faking the client origin. So a window that's really at (0, // We may be faking the client origin. So a window that's
// 30) may appear (to wxWin apps) to be at (0, 0). // really at (0, 30) may appear (to wxWin apps) to be at (0, 0).
wxPoint pt(parent->GetClientAreaOrigin()); wxPoint pt(parent->GetClientAreaOrigin());
point.x -= pt.x; point.x -= pt.x;
point.y -= pt.y; point.y -= pt.y;
@@ -1541,6 +1544,42 @@ void wxWindowMSW::DoClientToScreen(int *x, int *y) const
*y = pt.y; *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) void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
{ {
// TODO: is this consistent with other platforms? // 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) if (height < 0)
height = 0; height = 0;
// if our parent had prepared a defer window handle for us, use it (unless DoMoveSibling(m_hWnd, x, y, width, height);
// 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
} }
// set the size of the window: if the dimensions are positive, just use them, // 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 currentX, currentY;
int currentW, currentH; int currentW, currentH;
#if USE_DEFER_BUG_WORKAROUND
currentX = m_pendingPosition.x;
if (currentX == wxDefaultCoord)
GetPosition(&currentX, NULL);
currentY = m_pendingPosition.y;
if (currentY == wxDefaultCoord)
GetPosition(NULL, &currentY);
currentW = m_pendingSize.x;
if (currentW == wxDefaultCoord)
GetSize(&currentW, NULL);
currentH = m_pendingSize.y;
if (currentH == wxDefaultCoord)
GetSize(NULL, &currentH);
#else
GetPosition(&currentX, &currentY); GetPosition(&currentX, &currentY);
GetSize(&currentW, &currentH); GetSize(&currentW, &currentH);
#endif
// ... and don't do anything (avoiding flicker) if it's already ok // ... and don't do anything (avoiding flicker) if it's already ok
if ( x == currentX && y == currentY && 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 m_pendingPosition = wxPoint(x, y);
// We don't actually use the hdwp here, but we need to know whether to m_pendingSize = wxSize(width, height);
// 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
DoMoveWindow(x, y, 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")); wxLogLastError(_T("EndDeferWindowPos"));
} }
#if USE_DEFER_BUG_WORKAROUND
// Reset our children's pending pos/size values. // Reset our children's pending pos/size values.
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
node; node;
@@ -4261,9 +4248,8 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
child->m_pendingPosition = wxDefaultPosition; child->m_pendingPosition = wxDefaultPosition;
child->m_pendingSize = wxDefaultSize; child->m_pendingSize = wxDefaultSize;
} }
#endif
} }
#endif #endif // USE_DEFERRED_SIZING
return processed; return processed;
} }
@@ -6000,31 +5986,6 @@ bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam)
#endif // wxUSE_HOTKEY #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 // Not tested under WinCE
#ifndef __WXWINCE__ #ifndef __WXWINCE__