diff options
Diffstat (limited to 'bundles')
-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. |