Commit 16dfb1a0 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

comctl32/treeview: Fix TVS_SINGLEEXPAND notifications order.

parent b3a61c13
......@@ -192,6 +192,15 @@ static const struct message parent_expand_seq[] = {
{ 0 }
};
static const struct message parent_singleexpand_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA },
{ WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA },
{ WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND },
{ WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA },
{ WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA },
{ 0 }
};
static const struct message empty_seq[] = {
{ 0 }
};
......@@ -1231,6 +1240,25 @@ static void test_expandedimage(void)
DestroyWindow(hTree);
}
static void test_TVS_SINGLEEXPAND(void)
{
HWND hTree;
BOOL ret;
hTree = create_treeview_control();
SetWindowLongA(hTree, GWL_STYLE, GetWindowLong(hTree, GWL_STYLE) | TVS_SINGLEEXPAND);
/* to avoid paiting related notifications */
ShowWindow(hTree, SW_HIDE);
fill_tree(hTree);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot);
ok(ret, "got %d\n", ret);
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_singleexpand_seq, "singleexpand notifications", FALSE);
DestroyWindow(hTree);
}
START_TEST(treeview)
{
HMODULE hComctl32;
......@@ -1296,6 +1324,7 @@ START_TEST(treeview)
test_treeview_classinfo();
test_expandnotify();
test_rect_retrieval_after_expand_with_select();
test_TVS_SINGLEEXPAND();
if (!load_v6_module(&ctx_cookie, &hCtx))
{
......
......@@ -3305,7 +3305,7 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
static BOOL
TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
BOOL bExpandPartial, BOOL bUser)
BOOL partial, BOOL user)
{
LONG scrollDist;
LONG orgNextTop = 0;
......@@ -3313,7 +3313,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
TREEVIEW_ITEM *nextItem, *tmpItem;
BOOL sendsNotifications;
TRACE("(%p, %p, partial=%d, %d\n", infoPtr, wineItem, bExpandPartial, bUser);
TRACE("(%p, %p, partial=%d, %d\n", infoPtr, wineItem, partial, user);
if (wineItem->state & TVIS_EXPANDED)
return TRUE;
......@@ -3334,7 +3334,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
TRACE("TVE_EXPAND %p %s\n", wineItem, TREEVIEW_ItemName(wineItem));
sendsNotifications = bUser || ((wineItem->cChildren != 0) &&
sendsNotifications = user || ((wineItem->cChildren != 0) &&
!(wineItem->state & TVIS_EXPANDEDONCE));
if (sendsNotifications)
{
......@@ -3349,7 +3349,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
wineItem->state |= TVIS_EXPANDED;
if (bExpandPartial)
if (partial)
FIXME("TVE_EXPANDPARTIAL not implemented\n");
if (ISVISIBLE(wineItem))
......@@ -3415,6 +3415,58 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
return TRUE;
}
/* Handler for TVS_SINGLEEXPAND behaviour. Used on response
to mouse messages and TVM_SELECTITEM.
selection - previously selected item, used to collapse a part of a tree
item - new selected item
*/
static void TREEVIEW_SingleExpand(TREEVIEW_INFO *infoPtr,
HTREEITEM selection, HTREEITEM item)
{
TREEVIEW_ITEM *SelItem;
if ((infoPtr->dwStyle & TVS_SINGLEEXPAND) == 0 || infoPtr->hwndEdit) return;
TREEVIEW_SendTreeviewNotify(infoPtr, TVN_SINGLEEXPAND, TVC_UNKNOWN, TVIF_HANDLE | TVIF_PARAM, item, 0);
/*
* Close the previous selection all the way to the root
* as long as the new selection is not a child
*/
if(selection && (selection != item))
{
BOOL closeit = TRUE;
SelItem = item;
/* determine if the hitItem is a child of the currently selected item */
while(closeit && SelItem && TREEVIEW_ValidItem(infoPtr, SelItem) &&
(SelItem->parent != infoPtr->root))
{
closeit = (SelItem != selection);
SelItem = SelItem->parent;
}
if(closeit)
{
if(TREEVIEW_ValidItem(infoPtr, selection))
SelItem = selection;
while(SelItem && (SelItem != item) && TREEVIEW_ValidItem(infoPtr, SelItem) &&
SelItem->parent != infoPtr->root)
{
TREEVIEW_Collapse(infoPtr, SelItem, FALSE, FALSE);
SelItem = SelItem->parent;
}
}
}
/*
* Expand the current item
*/
TREEVIEW_Expand(infoPtr, item, FALSE, FALSE);
}
static BOOL
TREEVIEW_Toggle(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, BOOL bUser)
{
......@@ -4132,58 +4184,11 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
}
else if (ht.flags & (TVHT_ONITEMICON|TVHT_ONITEMLABEL)) /* select the item if the hit was inside of the icon or text */
{
/*
* if we are TVS_SINGLEEXPAND then we want this single click to
* do a bunch of things.
*/
if((infoPtr->dwStyle & TVS_SINGLEEXPAND) &&
(infoPtr->hwndEdit == 0))
{
TREEVIEW_ITEM *SelItem;
/*
* Send the notification
*/
TREEVIEW_SendTreeviewNotify(infoPtr, TVN_SINGLEEXPAND, TVC_UNKNOWN, TVIF_HANDLE | TVIF_PARAM, ht.hItem, 0);
/*
* Close the previous selection all the way to the root
* as long as the new selection is not a child
*/
if((infoPtr->selectedItem)
&& (infoPtr->selectedItem != ht.hItem))
{
BOOL closeit = TRUE;
SelItem = ht.hItem;
/* determine if the hitItem is a child of the currently selected item */
while(closeit && SelItem && TREEVIEW_ValidItem(infoPtr, SelItem) && (SelItem != infoPtr->root))
{
closeit = (SelItem != infoPtr->selectedItem);
SelItem = SelItem->parent;
}
if(closeit)
{
if(TREEVIEW_ValidItem(infoPtr, infoPtr->selectedItem))
SelItem = infoPtr->selectedItem;
while(SelItem && (SelItem != ht.hItem) && TREEVIEW_ValidItem(infoPtr, SelItem) && (SelItem != infoPtr->root))
{
TREEVIEW_Collapse(infoPtr, SelItem, FALSE, FALSE);
SelItem = SelItem->parent;
}
}
}
/*
* Expand the current item
*/
TREEVIEW_Expand(infoPtr, ht.hItem, TVE_TOGGLE, FALSE);
}
TREEVIEW_ITEM *selection = infoPtr->selectedItem;
/* Select the current item */
TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, ht.hItem, TVC_BYMOUSE);
TREEVIEW_SingleExpand(infoPtr, selection, ht.hItem);
}
else if (ht.flags & TVHT_ONITEMSTATEICON)
{
......@@ -4415,7 +4420,9 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect,
static LRESULT
TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item)
{
if (item != NULL && !TREEVIEW_ValidItem(infoPtr, item))
TREEVIEW_ITEM *selection = infoPtr->selectedItem;
if (item && !TREEVIEW_ValidItem(infoPtr, item))
return FALSE;
TRACE("%p (%s) %d\n", item, TREEVIEW_ItemName(item), wParam);
......@@ -4423,6 +4430,8 @@ TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item)
if (!TREEVIEW_DoSelectItem(infoPtr, wParam, item, TVC_UNKNOWN))
return FALSE;
TREEVIEW_SingleExpand(infoPtr, selection, item);
return TRUE;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment