]> git.saurik.com Git - wxWidgets.git/commitdiff
Freeze wxTreeCtrl in wxMSW by hiding it.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 13 Oct 2012 22:52:35 +0000 (22:52 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 13 Oct 2012 22:52:35 +0000 (22:52 +0000)
This is far from perfect but better than alternative as freezing this control
by sending WM_SETREDRAW to it can result in completely broken behaviour as
explained in http://support.microsoft.com/kb/130611. And not freezing it at
all shows horrible flicker when adding even a relatively small number of items
at once to the control because it recalculates and repositions its scrollbars
after every parent node addition.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72665 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/treectrl.h
src/msw/treectrl.cpp

index 83e4afa6f2d1f74758845348da053c472d9070f7..2be605fa2f7ea87448ec3d4f9dc0dbcc55995bb3 100644 (file)
@@ -212,6 +212,10 @@ public:
     virtual bool CanApplyThemeBorder() const { return false; }
 
 protected:
+    // Implement "update locking" in a custom way for this control.
+    virtual void DoFreeze();
+    virtual void DoThaw();
+
     // SetImageList helper
     void SetAnyImageList(wxImageList *imageList, int which);
 
index 9e99796c0ab74484a7a3fac7821d64c45d1c562d..0ac6f626c0ccec0da55434dc010c097c2f6d5ea8 100644 (file)
@@ -3923,4 +3923,32 @@ void wxTreeCtrl::DoSetItemState(const wxTreeItemId& item, int state)
     DoSetItem(&tvItem);
 }
 
+// ----------------------------------------------------------------------------
+// Update locking.
+// ----------------------------------------------------------------------------
+
+// Using WM_SETREDRAW with the native control is a bad idea as it's broken in
+// some Windows versions (see http://support.microsoft.com/kb/130611) and
+// 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.
+
+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);
+}
+
+void wxTreeCtrl::DoThaw()
+{
+    if ( IsShown() )
+        ::ShowWindow(GetHwnd(), SW_SHOW);
+}
+
 #endif // wxUSE_TREECTRL