summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java
diff options
context:
space:
mode:
authorSteve Northover <steve>2007-05-23 13:53:36 +0000
committerSteve Northover <steve>2007-05-23 13:53:36 +0000
commitea6bf58c55a1ccfba682400237d7c1f40ceeffab (patch)
treefbd6d5a9491a745e83bd50ac14fa9c476d48b2ee /bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java
parent5a83eff7ec24d270c869515e80cf37dbe30c0637 (diff)
downloadeclipse.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-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java59
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.