diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index 2be605fa2f..ac841554ae 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -216,6 +216,10 @@ protected: virtual void DoFreeze(); virtual void DoThaw(); + virtual void DoSetSize(int x, int y, + int width, int height, + int sizeFlags = wxSIZE_AUTO); + // SetImageList helper void SetAnyImageList(wxImageList *imageList, int which); @@ -336,6 +340,9 @@ private: // whether we need to deselect other items on mouse up bool m_mouseUpDeselect; + // The size to restore the control to when it is thawed, see DoThaw(). + wxSize m_thawnSize; + friend class wxTreeItemIndirectData; friend class wxTreeSortHelper; diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index 5593b2c298..485e203b54 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -30,6 +30,7 @@ #include "wx/treectrl.h" #include "wx/math.h" #include "wx/renderer.h" +#include "wx/wupdlock.h" #ifdef __WIN32__ // this is not supported by native control @@ -122,6 +123,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) MENU_LINK(EnsureVisible) MENU_LINK(SetFocus) MENU_LINK(AddItem) + MENU_LINK(AddManyItems) MENU_LINK(InsertItem) MENU_LINK(IncIndent) MENU_LINK(DecIndent) @@ -264,6 +266,7 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h) tree_menu->Append(TreeTest_CollapseAndReset, wxT("C&ollapse and reset")); tree_menu->AppendSeparator(); tree_menu->Append(TreeTest_AddItem, wxT("Append a &new item")); + tree_menu->Append(TreeTest_AddManyItems, wxT("Appends &many items")); tree_menu->Append(TreeTest_InsertItem, wxT("&Insert a new item")); tree_menu->Append(TreeTest_Delete, wxT("&Delete this item")); tree_menu->Append(TreeTest_DeleteChildren, wxT("Delete &children")); @@ -782,6 +785,17 @@ void MyFrame::OnAddItem(wxCommandEvent& WXUNUSED(event)) MyTreeCtrl::TreeCtrlIcon_File */ ); } +void MyFrame::OnAddManyItems(wxCommandEvent& WXUNUSED(event)) +{ + wxWindowUpdateLocker lockUpdates(this); + + const wxTreeItemId root = m_treeCtrl->GetRootItem(); + for ( int n = 0; n < 1000; n++ ) + { + m_treeCtrl->AppendItem(root, wxString::Format("Item #%03d", n)); + } +} + void MyFrame::OnIncIndent(wxCommandEvent& WXUNUSED(event)) { unsigned int indent = m_treeCtrl->GetIndent(); diff --git a/samples/treectrl/treetest.h b/samples/treectrl/treetest.h index 8c29d7e2e9..a798f292f4 100644 --- a/samples/treectrl/treetest.h +++ b/samples/treectrl/treetest.h @@ -242,6 +242,7 @@ public: void OnSortRev(wxCommandEvent& WXUNUSED(event)) { DoSort(true); } void OnAddItem(wxCommandEvent& event); + void OnAddManyItems(wxCommandEvent& event); void OnInsertItem(wxCommandEvent& event); void OnIncIndent(wxCommandEvent& event); @@ -350,6 +351,7 @@ enum TreeTest_EnsureVisible, TreeTest_SetFocus, TreeTest_AddItem, + TreeTest_AddManyItems, TreeTest_InsertItem, TreeTest_IncIndent, TreeTest_DecIndent, diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 2fbf27353f..191a26fc00 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -3932,23 +3932,42 @@ void wxTreeCtrl::DoSetItemState(const wxTreeItemId& item, int state) // doesn't seem to do anything in other ones (e.g. under Windows 7 the tree // control keeps updating its scrollbars while the items are added to it, // resulting in horrible flicker when adding even a couple of dozen items). -// So we hide it instead of freezing -- this still flickers, but actually not -// as badly as it would if we didn't do it. +// So we resize it to the smallest possible size instead of freezing -- this +// still flickers, but actually not as badly as it would if we didn't do it. void wxTreeCtrl::DoFreeze() { - // Notice that we don't call wxWindow::Hide() here as we want the window to - // remain shown from wxWidgets point of view and also because - // wxWindowMSW::Show() calls Do{Freeze,Thaw}() itself, so we'd get into - // infinite recursion this way. if ( IsShown() ) - ::ShowWindow(GetHwnd(), SW_HIDE); + { + RECT rc; + ::GetWindowRect(GetHwnd(), &rc); + m_thawnSize = wxRectFromRECT(rc).GetSize(); + + ::SetWindowPos(GetHwnd(), 0, 0, 0, 1, 1, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE); + } } void wxTreeCtrl::DoThaw() { if ( IsShown() ) - ::ShowWindow(GetHwnd(), SW_SHOW); + { + if ( m_thawnSize != wxDefaultSize ) + { + ::SetWindowPos(GetHwnd(), 0, 0, 0, m_thawnSize.x, m_thawnSize.y, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } +} + +// We also need to override DoSetSize() to ensure that m_thawnSize is reset if +// the window is resized while being frozen -- in this case, we need to avoid +// resizing it back to its original, pre-freeze, size when it's thawed. +void wxTreeCtrl::DoSetSize(int x, int y, int width, int height, int sizeFlags) +{ + m_thawnSize = wxDefaultSize; + + wxTreeCtrlBase::DoSetSize(x, y, width, height, sizeFlags); } #endif // wxUSE_TREECTRL