From 1d19eb15d4abfdd14dccc5ac05b83c0ee1a1ace1 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 23 Nov 2015 00:25:11 +0300 Subject: [PATCH] comctl32: Item with negative cChildren acts as if it actually had children. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- 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 917df23494f..92504c11820 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 ffb5981b107..695745c7a86 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)