Nikolay Sivov : comctl32: Item with negative cChildren acts as if it actually had children.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Nov 23 09:59:47 CST 2015


Module: wine
Branch: master
Commit: 1d19eb15d4abfdd14dccc5ac05b83c0ee1a1ace1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1d19eb15d4abfdd14dccc5ac05b83c0ee1a1ace1

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Nov 23 00:25:11 2015 +0300

comctl32: Item with negative cChildren acts as if it actually had children.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/comctl32/tests/treeview.c | 22 +++++++++++++++++++++-
 dlls/comctl32/treeview.c       |  5 +++--
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c
index 917df23..92504c1 100644
--- a/dlls/comctl32/tests/treeview.c
+++ b/dlls/comctl32/tests/treeview.c
@@ -1193,7 +1193,9 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam,
 
             case TVN_ENDLABELEDITA: return TRUE;
             case TVN_ITEMEXPANDINGA:
-                ok(pTreeView->itemNew.mask ==
+              {
+                UINT newmask = pTreeView->itemNew.mask & ~TVIF_CHILDREN;
+                ok(newmask ==
                    (TVIF_HANDLE | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_PARAM | TVIF_STATE),
                    "got wrong mask %x\n", pTreeView->itemNew.mask);
                 ok(pTreeView->itemOld.mask == 0,
@@ -1207,6 +1209,7 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam,
                   ok(ret == TRUE, "got %lu\n", ret);
                 }
                 break;
+              }
             case TVN_ITEMEXPANDEDA:
                 ok(pTreeView->itemNew.mask & TVIF_STATE, "got wrong mask %x\n", pTreeView->itemNew.mask);
                 ok(pTreeView->itemNew.state & (TVIS_EXPANDED|TVIS_EXPANDEDONCE),
@@ -1529,6 +1532,7 @@ static void test_get_insertmarkcolor(void)
 
 static void test_expandnotify(void)
 {
+    HTREEITEM hitem;
     HWND hTree;
     BOOL ret;
     TVITEMA item;
@@ -1679,6 +1683,22 @@ static void test_expandnotify(void)
     expect(FALSE, ret);
     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_empty_kb_seq, "expand node with no children", FALSE);
 
+    /* stay on current selection and set non-zero children count */
+    hitem = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CARET, 0);
+    ok(hitem != NULL, "got %p\n", hitem);
+
+    item.hItem = hitem;
+    item.mask = TVIF_CHILDREN;
+    item.cChildren = 0x80000000;
+
+    ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item);
+    expect(TRUE, ret);
+
+    flush_sequences(sequences, NUM_MSG_SEQUENCES);
+    ret = SendMessageA(hTree, WM_KEYDOWN, VK_ADD, 0);
+    expect(FALSE, ret);
+    ok_sequence(sequences, PARENT_SEQ_INDEX, parent_collapse_2nd_kb_seq, "expand node with children", FALSE);
+
     DestroyWindow(hTree);
 }
 
diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c
index ffb5981..695745c 100644
--- a/dlls/comctl32/treeview.c
+++ b/dlls/comctl32/treeview.c
@@ -816,8 +816,9 @@ static BOOL
 TREEVIEW_HasChildren(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
 {
     TREEVIEW_UpdateDispInfo(infoPtr, item, TVIF_CHILDREN);
-
-    return item->cChildren > 0;
+    /* Protect for a case when callback field is not changed by a host,
+       otherwise negative values trigger normal notifications. */
+    return item->cChildren != 0 && item->cChildren != I_CHILDRENCALLBACK;
 }
 
 static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand)




More information about the wine-cvs mailing list