comctl32: Use single notification message for setting all item state with LVM_SETITEMSTATE (LVS_OWNERDATA case only).
This commit is contained in:
parent
1478648b9f
commit
b326426fec
|
@ -8809,26 +8809,31 @@ static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, const PO
|
|||
* PARAMETER(S):
|
||||
* [I] infoPtr : valid pointer to the listview structure
|
||||
* [I] nItem : item index
|
||||
* [I] lpLVItem : item or subitem info
|
||||
* [I] item : item or subitem info
|
||||
*
|
||||
* RETURN:
|
||||
* SUCCESS : TRUE
|
||||
* FAILURE : FALSE
|
||||
*/
|
||||
static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITEMW *lpLVItem)
|
||||
static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITEMW *item)
|
||||
{
|
||||
BOOL bResult = TRUE;
|
||||
BOOL ret = TRUE;
|
||||
LVITEMW lvItem;
|
||||
|
||||
if (!item) return FALSE;
|
||||
|
||||
lvItem.iItem = nItem;
|
||||
lvItem.iSubItem = 0;
|
||||
lvItem.mask = LVIF_STATE;
|
||||
lvItem.state = lpLVItem->state;
|
||||
lvItem.stateMask = lpLVItem->stateMask;
|
||||
TRACE("lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
|
||||
lvItem.state = item->state;
|
||||
lvItem.stateMask = item->stateMask;
|
||||
TRACE("item=%s\n", debuglvitem_t(&lvItem, TRUE));
|
||||
|
||||
if (nItem == -1)
|
||||
{
|
||||
UINT oldstate = 0;
|
||||
BOOL notify;
|
||||
|
||||
/* select all isn't allowed in LVS_SINGLESEL */
|
||||
if ((lvItem.state & lvItem.stateMask & LVIS_SELECTED) && (infoPtr->dwStyle & LVS_SINGLESEL))
|
||||
return FALSE;
|
||||
|
@ -8836,14 +8841,40 @@ static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITE
|
|||
/* focus all isn't allowed */
|
||||
if (lvItem.state & lvItem.stateMask & LVIS_FOCUSED) return FALSE;
|
||||
|
||||
notify = infoPtr->bDoChangeNotify;
|
||||
if (infoPtr->dwStyle & LVS_OWNERDATA)
|
||||
{
|
||||
infoPtr->bDoChangeNotify = FALSE;
|
||||
if (!(lvItem.state & LVIS_SELECTED) && LISTVIEW_GetSelectedCount(infoPtr))
|
||||
oldstate |= LVIS_SELECTED;
|
||||
if (infoPtr->nFocusedItem != -1) oldstate |= LVIS_FOCUSED;
|
||||
}
|
||||
|
||||
/* apply to all items */
|
||||
for (lvItem.iItem = 0; lvItem.iItem < infoPtr->nItemCount; lvItem.iItem++)
|
||||
if (!LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE)) bResult = FALSE;
|
||||
if (!LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE)) ret = FALSE;
|
||||
|
||||
if (infoPtr->dwStyle & LVS_OWNERDATA)
|
||||
{
|
||||
NMLISTVIEW nmlv;
|
||||
|
||||
infoPtr->bDoChangeNotify = notify;
|
||||
|
||||
nmlv.iItem = -1;
|
||||
nmlv.iSubItem = 0;
|
||||
nmlv.uNewState = lvItem.state & lvItem.stateMask;
|
||||
nmlv.uOldState = oldstate & lvItem.stateMask;
|
||||
nmlv.uChanged = LVIF_STATE;
|
||||
nmlv.ptAction.x = nmlv.ptAction.y = 0;
|
||||
nmlv.lParam = 0;
|
||||
|
||||
notify_listview(infoPtr, LVN_ITEMCHANGED, &nmlv);
|
||||
}
|
||||
}
|
||||
else
|
||||
bResult = LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE);
|
||||
ret = LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE);
|
||||
|
||||
return bResult;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -11410,7 +11441,6 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, (POINT*)lParam);
|
||||
|
||||
case LVM_SETITEMSTATE:
|
||||
if (lParam == 0) return FALSE;
|
||||
return LISTVIEW_SetItemState(infoPtr, (INT)wParam, (LPLVITEMW)lParam);
|
||||
|
||||
case LVM_SETITEMTEXTA:
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright 2006 Mike McCormack for CodeWeavers
|
||||
* Copyright 2007 George Gov
|
||||
* Copyright 2009-2011 Nikolay Sivov
|
||||
* Copyright 2009-2012 Nikolay Sivov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -50,11 +50,11 @@ static HWND hwndparent, hwndparentW;
|
|||
static BOOL blockEdit;
|
||||
/* return nonzero on NM_HOVER */
|
||||
static BOOL g_block_hover;
|
||||
/* dumps LVN_ITEMCHANGED message data */
|
||||
static BOOL g_dump_itemchanged;
|
||||
/* notification data for LVN_ITEMCHANGED */
|
||||
static NMLISTVIEW g_nmlistview;
|
||||
/* format reported to control:
|
||||
-1 falls to defproc, anything else returned */
|
||||
static INT notifyFormat;
|
||||
static INT notifyFormat;
|
||||
/* indicates we're running < 5.80 version */
|
||||
static BOOL g_is_below_5;
|
||||
/* item data passed to LVN_GETDISPINFOA */
|
||||
|
@ -391,11 +391,9 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP
|
|||
}
|
||||
break;
|
||||
case LVN_ITEMCHANGED:
|
||||
if (g_dump_itemchanged)
|
||||
{
|
||||
NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;
|
||||
trace("LVN_ITEMCHANGED: item=%d,new=%x,old=%x,changed=%x\n",
|
||||
nmlv->iItem, nmlv->uNewState, nmlv->uOldState, nmlv->uChanged);
|
||||
g_nmlistview = *nmlv;
|
||||
}
|
||||
break;
|
||||
case LVN_GETDISPINFOA:
|
||||
|
@ -2768,35 +2766,68 @@ static void test_ownerdata(void)
|
|||
item.stateMask = LVIS_SELECTED;
|
||||
item.state = LVIS_SELECTED;
|
||||
|
||||
g_dump_itemchanged = TRUE;
|
||||
memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
|
||||
res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
g_dump_itemchanged = FALSE;
|
||||
ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
|
||||
ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
|
||||
ok(g_nmlistview.uNewState == LVIS_SELECTED, "got new state 0x%08x\n", g_nmlistview.uNewState);
|
||||
ok(g_nmlistview.uOldState == 0, "got old state 0x%08x\n", g_nmlistview.uOldState);
|
||||
ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
|
||||
ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
|
||||
ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq,
|
||||
"ownerdata select all notification", TRUE);
|
||||
"ownerdata select all notification", FALSE);
|
||||
|
||||
/* select all again, note that all items are selected already */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
item.stateMask = LVIS_SELECTED;
|
||||
item.state = LVIS_SELECTED;
|
||||
g_dump_itemchanged = TRUE;
|
||||
|
||||
memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
|
||||
res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
g_dump_itemchanged = FALSE;
|
||||
ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
|
||||
ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
|
||||
ok(g_nmlistview.uNewState == LVIS_SELECTED, "got new state 0x%08x\n", g_nmlistview.uNewState);
|
||||
ok(g_nmlistview.uOldState == 0, "got old state 0x%08x\n", g_nmlistview.uOldState);
|
||||
ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
|
||||
ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
|
||||
ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq,
|
||||
"ownerdata select all notification", TRUE);
|
||||
"ownerdata select all notification", FALSE);
|
||||
|
||||
/* deselect all */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
item.stateMask = LVIS_SELECTED;
|
||||
item.state = 0;
|
||||
g_dump_itemchanged = TRUE;
|
||||
|
||||
memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
|
||||
res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
g_dump_itemchanged = FALSE;
|
||||
ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
|
||||
ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
|
||||
ok(g_nmlistview.uNewState == 0, "got new state 0x%08x\n", g_nmlistview.uNewState);
|
||||
ok(g_nmlistview.uOldState == LVIS_SELECTED, "got old state 0x%08x\n", g_nmlistview.uOldState);
|
||||
ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
|
||||
ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
|
||||
ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_deselect_all_parent_seq,
|
||||
"ownerdata deselect all notification", TRUE);
|
||||
|
||||
/* nothing selected, deselect all again */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
item.stateMask = LVIS_SELECTED;
|
||||
item.state = 0;
|
||||
|
||||
res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "ownerdata deselect all notification", TRUE);
|
||||
|
||||
/* select one, then deselect all */
|
||||
item.stateMask = LVIS_SELECTED;
|
||||
item.state = LVIS_SELECTED;
|
||||
|
@ -2805,10 +2836,18 @@ static void test_ownerdata(void)
|
|||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
item.stateMask = LVIS_SELECTED;
|
||||
item.state = 0;
|
||||
g_dump_itemchanged = TRUE;
|
||||
|
||||
memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
|
||||
res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
g_dump_itemchanged = FALSE;
|
||||
ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
|
||||
ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
|
||||
ok(g_nmlistview.uNewState == 0, "got new state 0x%08x\n", g_nmlistview.uNewState);
|
||||
ok(g_nmlistview.uOldState == LVIS_SELECTED, "got old state 0x%08x\n", g_nmlistview.uOldState);
|
||||
ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
|
||||
ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
|
||||
ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_deselect_all_parent_seq,
|
||||
"ownerdata select all notification", TRUE);
|
||||
|
||||
|
@ -2824,16 +2863,18 @@ static void test_ownerdata(void)
|
|||
item.stateMask = LVIS_FOCUSED;
|
||||
res = SendMessageA(hwnd, LVM_GETITEMSTATE, 0, LVIS_FOCUSED);
|
||||
expect(0, res);
|
||||
|
||||
/* setting all to focused returns failure value */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
item.stateMask = LVIS_FOCUSED;
|
||||
item.state = LVIS_FOCUSED;
|
||||
g_dump_itemchanged = TRUE;
|
||||
|
||||
res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
|
||||
expect(FALSE, res);
|
||||
g_dump_itemchanged = FALSE;
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
|
||||
"ownerdata focus all notification", FALSE);
|
||||
|
||||
/* focus single item, remove all */
|
||||
item.stateMask = LVIS_FOCUSED;
|
||||
item.state = LVIS_FOCUSED;
|
||||
|
@ -2842,32 +2883,58 @@ static void test_ownerdata(void)
|
|||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
item.stateMask = LVIS_FOCUSED;
|
||||
item.state = 0;
|
||||
g_dump_itemchanged = TRUE;
|
||||
|
||||
memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
|
||||
res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
g_dump_itemchanged = FALSE;
|
||||
ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
|
||||
ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
|
||||
ok(g_nmlistview.uNewState == 0, "got new state 0x%08x\n", g_nmlistview.uNewState);
|
||||
ok(g_nmlistview.uOldState == LVIS_FOCUSED, "got old state 0x%08x\n", g_nmlistview.uOldState);
|
||||
ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
|
||||
ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
|
||||
ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_defocus_all_parent_seq,
|
||||
"ownerdata remove focus all notification", TRUE);
|
||||
|
||||
/* set all cut */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
item.stateMask = LVIS_CUT;
|
||||
item.state = LVIS_CUT;
|
||||
g_dump_itemchanged = TRUE;
|
||||
|
||||
memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
|
||||
res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
g_dump_itemchanged = FALSE;
|
||||
ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
|
||||
ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
|
||||
ok(g_nmlistview.uNewState == LVIS_CUT, "got new state 0x%08x\n", g_nmlistview.uNewState);
|
||||
ok(g_nmlistview.uOldState == 0, "got old state 0x%08x\n", g_nmlistview.uOldState);
|
||||
ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
|
||||
ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
|
||||
ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq,
|
||||
"ownerdata cut all notification", TRUE);
|
||||
"ownerdata cut all notification", FALSE);
|
||||
|
||||
/* all marked cut, try again */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
item.stateMask = LVIS_CUT;
|
||||
item.state = LVIS_CUT;
|
||||
g_dump_itemchanged = TRUE;
|
||||
|
||||
memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
|
||||
res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
g_dump_itemchanged = FALSE;
|
||||
ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
|
||||
ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
|
||||
ok(g_nmlistview.uNewState == LVIS_CUT, "got new state 0x%08x\n", g_nmlistview.uNewState);
|
||||
ok(g_nmlistview.uOldState == 0, "got old state 0x%08x\n", g_nmlistview.uOldState);
|
||||
ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
|
||||
ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
|
||||
ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq,
|
||||
"ownerdata cut all notification #2", TRUE);
|
||||
"ownerdata cut all notification #2", FALSE);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
|
|
Loading…
Reference in New Issue