diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h index 1dedb608c6..b3dcb0260b 100644 --- a/include/wx/generic/listctrl.h +++ b/include/wx/generic/listctrl.h @@ -215,9 +215,6 @@ protected: virtual wxSize DoGetBestSize() const; - virtual void DoFreeze(); - virtual void DoThaw(); - // return the text for the given column of the given item virtual wxString OnGetItemText(long item, long column) const; diff --git a/include/wx/msw/toplevel.h b/include/wx/msw/toplevel.h index d3422813f0..1434359e85 100644 --- a/include/wx/msw/toplevel.h +++ b/include/wx/msw/toplevel.h @@ -75,8 +75,6 @@ public: virtual bool SetTransparent(wxByte alpha); virtual bool CanSetTransparent(); - virtual void AddChild( wxWindowBase *child ); - // implementation from now on // -------------------------- diff --git a/include/wx/window.h b/include/wx/window.h index 33d33ce50d..3b39c5b321 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -888,16 +888,10 @@ public: virtual void ClearBackground(); // freeze the window: don't redraw it until it is thawed - void Freeze() { if ( !m_freezeCount++ ) DoFreeze(); } + void Freeze(); // thaw the window: redraw it after it had been frozen - void Thaw() - { - wxASSERT_MSG( m_freezeCount, "Thaw() without matching Freeze()" ); - - if ( !--m_freezeCount ) - DoThaw(); - } + void Thaw(); // return true if window had been frozen and not unthawed yet bool IsFrozen() const { return m_freezeCount != 0; } diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 6b80b11927..838be57cc7 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -928,6 +928,52 @@ bool wxWindowBase::IsTopLevel() const return false; } +// ---------------------------------------------------------------------------- +// Freeze/Thaw +// ---------------------------------------------------------------------------- + +void wxWindowBase::Freeze() +{ + if ( !m_freezeCount++ ) + { + // physically freeze this window: + DoFreeze(); + + // and recursively freeze all children: + for ( wxWindowList::iterator i = GetChildren().begin(); + i != GetChildren().end(); ++i ) + { + wxWindow *child = *i; + if ( child->IsTopLevel() ) + continue; + + child->Freeze(); + } + } +} + +void wxWindowBase::Thaw() +{ + wxASSERT_MSG( m_freezeCount, "Thaw() without matching Freeze()" ); + + if ( !--m_freezeCount ) + { + // recursively thaw all children: + for ( wxWindowList::iterator i = GetChildren().begin(); + i != GetChildren().end(); ++i ) + { + wxWindow *child = *i; + if ( child->IsTopLevel() ) + continue; + + child->Thaw(); + } + + // physically thaw this window: + DoThaw(); + } +} + // ---------------------------------------------------------------------------- // reparenting the window // ---------------------------------------------------------------------------- @@ -943,12 +989,22 @@ void wxWindowBase::AddChild(wxWindowBase *child) GetChildren().Append((wxWindow*)child); child->SetParent(this); + + // adding a child while frozen will assert when thawn, so freeze it as if + // it had been already present when we were frozen + if ( IsFrozen() && !child->IsTopLevel() ) + child->Freeze(); } void wxWindowBase::RemoveChild(wxWindowBase *child) { wxCHECK_RET( child, wxT("can't remove a NULL child") ); + // removing a child while frozen may result in permanently frozen window + // if used e.g. from Reparent(), so thaw it + if ( IsFrozen() && !child->IsTopLevel() ) + child->Thaw(); + GetChildren().DeleteObject((wxWindow *)child); child->SetParent(NULL); } diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index f6bb4d3199..bf34d03800 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -5901,14 +5901,4 @@ void wxGenericListCtrl::Refresh(bool eraseBackground, const wxRect *rect) } } -void wxGenericListCtrl::DoFreeze() -{ - m_mainWin->Freeze(); -} - -void wxGenericListCtrl::DoThaw() -{ - m_mainWin->Thaw(); -} - #endif // wxUSE_LISTCTRL diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 65dfa44586..f87a982735 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -1175,49 +1175,14 @@ bool wxTopLevelWindowMSW::CanSetTransparent() void wxTopLevelWindowMSW::DoFreeze() { - if ( IsShown() ) - { - for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - node; - node = node->GetNext() ) - { - wxWindow *child = node->GetData(); - if ( child->IsTopLevel() ) - continue; - - child->Freeze(); - } - } + // do nothing: freezing toplevel window causes paint and mouse events + // to go through it any TLWs under it, so the best we can do is to freeze + // all children -- and wxWindowBase::Freeze() does that } void wxTopLevelWindowMSW::DoThaw() { - if ( IsShown() ) - { - for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - node; - node = node->GetNext() ) - { - wxWindow *child = node->GetData(); - if ( child->IsTopLevel() ) - continue; - - child->Thaw(); - } - } -} - - -void wxTopLevelWindowMSW::AddChild(wxWindowBase *child) -{ - // adding a child while frozen will assert when thawn, so freeze it as if - // it had been already present when we were frozen - if ( child && !child->IsTopLevel() && IsFrozen() ) - { - child->Freeze(); - } - - wxTopLevelWindowBase::AddChild(child); + // intentionally empty -- see DoFreeze() }