diff options
author | Steve Northover <steve> | 2007-05-23 13:53:36 +0000 |
---|---|---|
committer | Steve Northover <steve> | 2007-05-23 13:53:36 +0000 |
commit | ea6bf58c55a1ccfba682400237d7c1f40ceeffab (patch) | |
tree | fbd6d5a9491a745e83bd50ac14fa9c476d48b2ee /bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java | |
parent | 5a83eff7ec24d270c869515e80cf37dbe30c0637 (diff) | |
download | eclipse.platform.swt-ea6bf58c55a1ccfba682400237d7c1f40ceeffab.tar.gz eclipse.platform.swt-ea6bf58c55a1ccfba682400237d7c1f40ceeffab.tar.xz eclipse.platform.swt-ea6bf58c55a1ccfba682400237d7c1f40ceeffab.zip |
188381 - Tree Viewer Collapse Extremely Slow on Vista
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java')
-rwxr-xr-x | bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java index 41b64be3f1..12182df2d0 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java @@ -1331,7 +1331,28 @@ LRESULT CDDS_POSTPAINT (NMTVCUSTOMDRAW nmcd, int wParam, int lParam) { int index = indexOf (sortColumn); if (index != -1) { int top = nmcd.top; - int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_LASTVISIBLE, 0); + /* + * Bug in Windows. For some reason, during a collapse, + * when TVM_GETNEXTITEM is sent with TVGN_LASTVISIBLE + * and the collapse causes the item being collapsed + * to become the last visible item in the tree, the + * message takes a long time to process. In order for + * the slowness to happen, the children of the item + * must have children. Times of up to 11 seconds have + * been observed with 23 children, each having one + * child. The fix is to use the bottom partially + * visible item rather than the last possible item + * that could be visible. + * + * NOTE: This problem only happens on Vista during + * WM_NOTIFY with NM_CUSTOMDRAW and CDDS_POSTPAINT. + */ + int hItem = 0; + if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { + hItem = getBottomItem (); + } else { + hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_LASTVISIBLE, 0); + } if (hItem != 0) { RECT rect = new RECT (); rect.left = hItem; @@ -1368,7 +1389,28 @@ LRESULT CDDS_POSTPAINT (NMTVCUSTOMDRAW nmcd, int wParam, int lParam) { } int height = 0; RECT rect = new RECT (); - int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_LASTVISIBLE, 0); + /* + * Bug in Windows. For some reason, during a collapse, + * when TVM_GETNEXTITEM is sent with TVGN_LASTVISIBLE + * and the collapse causes the item being collapsed + * to become the last visible item in the tree, the + * message takes a long time to process. In order for + * the slowness to happen, the children of the item + * must have children. Times of up to 11 seconds have + * been observed with 23 children, each having one + * child. The fix is to use the bottom partially + * visible item rather than the last possible item + * that could be visible. + * + * NOTE: This problem only happens on Vista during + * WM_NOTIFY with NM_CUSTOMDRAW and CDDS_POSTPAINT. + */ + int hItem = 0; + if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { + hItem = getBottomItem (); + } else { + hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_LASTVISIBLE, 0); + } if (hItem != 0) { rect.left = hItem; if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, rect) != 0) { @@ -2757,6 +2799,19 @@ Point getImageSize () { return new Point (0, getItemHeight ()); } +int getBottomItem () { + int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); + if (hItem == 0) return 0; + int index = 0, count = OS.SendMessage (handle, OS.TVM_GETVISIBLECOUNT, 0, 0); + while (index < count) { + int hNextItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hItem); + if (hNextItem == 0) return hItem; + hItem = hNextItem; + index++; + } + return hItem; +} + /** * Returns the column at the given, zero-relative index in the * receiver. Throws an exception if the index is out of range. |