Add wxWindow::BeginRepositioningChildren() and EndRepositioningChildren().

This is just a refactoring of wxMSW code to make it possible to use deferred
window positioning from other places in subsequent commits.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74066 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2013-05-31 23:21:03 +00:00
parent 4300317631
commit 1a986642f5
5 changed files with 156 additions and 44 deletions

View File

@@ -5109,11 +5109,9 @@ bool wxWindowMSW::HandleExitSizeMove()
return HandleWindowEvent(event);
}
bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
bool wxWindowMSW::BeginRepositioningChildren()
{
#if wxUSE_DEFERRED_SIZING
// when we resize this window, its children are probably going to be
// repositioned as well, prepare to use DeferWindowPos() for them
int numChildren = 0;
for ( HWND child = ::GetWindow(GetHwndOf(this), GW_CHILD);
child;
@@ -5122,23 +5120,60 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
numChildren ++;
}
// Protect against valid m_hDWP being overwritten
bool useDefer = false;
// Nothing is gained by deferring the repositioning of a single child.
if ( numChildren < 2 )
return false;
if ( numChildren > 1 )
// Protect against valid m_hDWP being overwritten
if ( m_hDWP )
return false;
m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
if ( !m_hDWP )
{
if (!m_hDWP)
{
m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
if ( !m_hDWP )
{
wxLogLastError(wxT("BeginDeferWindowPos"));
}
if (m_hDWP)
useDefer = true;
}
wxLogLastError(wxT("BeginDeferWindowPos"));
return false;
}
// Return true to indicate that EndDeferWindowPos() should be called.
return true;
#endif // wxUSE_DEFERRED_SIZING
}
void wxWindowMSW::EndRepositioningChildren()
{
#if wxUSE_DEFERRED_SIZING
wxASSERT_MSG( m_hDWP, wxS("Shouldn't be called") );
// reset m_hDWP to NULL so that child windows don't try to use our
// m_hDWP after we call EndDeferWindowPos() on it (this shouldn't
// happen anyhow normally but who knows what weird flow of control we
// may have depending on what the users EVT_SIZE handler does...)
HDWP hDWP = (HDWP)m_hDWP;
m_hDWP = NULL;
// do put all child controls in place at once
if ( !::EndDeferWindowPos(hDWP) )
{
wxLogLastError(wxT("EndDeferWindowPos"));
}
// Reset our children's pending pos/size values.
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
node;
node = node->GetNext() )
{
wxWindowMSW * const child = node->GetData();
child->MSWEndDeferWindowPos();
}
#endif // wxUSE_DEFERRED_SIZING
}
bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
{
// when we resize this window, its children are probably going to be
// repositioned as well, prepare to use DeferWindowPos() for them
ChildrenRepositioningGuard repositionGuard(this);
// update this window size
bool processed = false;
@@ -5171,34 +5206,6 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
processed = HandleWindowEvent(event);
}
#if wxUSE_DEFERRED_SIZING
// and finally change the positions of all child windows at once
if ( useDefer && m_hDWP )
{
// reset m_hDWP to NULL so that child windows don't try to use our
// m_hDWP after we call EndDeferWindowPos() on it (this shouldn't
// happen anyhow normally but who knows what weird flow of control we
// may have depending on what the users EVT_SIZE handler does...)
HDWP hDWP = (HDWP)m_hDWP;
m_hDWP = NULL;
// do put all child controls in place at once
if ( !::EndDeferWindowPos(hDWP) )
{
wxLogLastError(wxT("EndDeferWindowPos"));
}
// Reset our children's pending pos/size values.
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
node;
node = node->GetNext() )
{
wxWindowMSW * const child = node->GetData();
child->MSWEndDeferWindowPos();
}
}
#endif // wxUSE_DEFERRED_SIZING
return processed;
}