Module: wine Branch: master Commit: 7bacd7aa387ce98acbbc5541ae9a0d091bc0bb57 URL: https://source.winehq.org/git/wine.git/?a=commit;h=7bacd7aa387ce98acbbc5541a...
Author: Alistair Leslie-Hughes leslie_alistair@hotmail.com Date: Wed Aug 14 09:42:58 2019 +0300
comctl32/listview: Don't report current item state in change notification when state change wasn't requested.
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/comctl32/listview.c | 7 ++-- dlls/comctl32/tests/listview.c | 82 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 2717812..acf6f31 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -4259,8 +4259,11 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
memset(&nmlv, 0, sizeof(NMLISTVIEW)); nmlv.iItem = lpLVItem->iItem; - nmlv.uNewState = (item.state & ~stateMask) | (lpLVItem->state & stateMask); - nmlv.uOldState = item.state; + if (lpLVItem->mask & LVIF_STATE) + { + nmlv.uNewState = (item.state & ~stateMask) | (lpLVItem->state & stateMask); + nmlv.uOldState = item.state; + } nmlv.uChanged = uChanged ? uChanged : lpLVItem->mask; nmlv.lParam = item.lParam;
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 48612db..48cd614 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -6458,6 +6458,86 @@ static void test_LVM_GETCOUNTPERPAGE(void) ok(ret, "Failed to unregister test class.\n"); }
+static void test_item_state_change(void) +{ + static const DWORD styles[] = { LVS_ICON, LVS_LIST, LVS_REPORT, LVS_SMALLICON }; + LVITEMA item; + HWND hwnd; + DWORD res; + int i; + + for (i = 0; i < ARRAY_SIZE(styles); i++) + { + hwnd = create_listview_control(styles[i]); + + insert_item(hwnd, 0); + + /* LVM_SETITEMSTATE with mask */ + memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview)); + memset(&item, 0, sizeof(item)); + item.mask = LVIF_STATE; + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + ok(res, "Failed to set item state.\n"); + + ok(g_nmlistview.iItem == item.iItem, "Unexpected item %d.\n", g_nmlistview.iItem); + ok(g_nmlistview.iSubItem == item.iSubItem, "Unexpected subitem %d.\n", g_nmlistview.iSubItem); + ok(g_nmlistview.lParam == item.lParam, "Unexpected lParam.\n"); + 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); + + /* LVM_SETITEMSTATE 0 mask */ + memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview)); + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_SELECTED; + item.state = 0; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + ok(res, "Failed to set item state.\n"); + + ok(g_nmlistview.iItem == item.iItem, "Unexpected item %d.\n", g_nmlistview.iItem); + ok(g_nmlistview.iSubItem == item.iSubItem, "Unexpected subitem %d.\n", g_nmlistview.iSubItem); + ok(g_nmlistview.lParam == item.lParam, "Unexpected lParam.\n"); + ok(g_nmlistview.uNewState == 0, "Unexpected new state %#x.\n", g_nmlistview.uNewState); + ok(g_nmlistview.uOldState == LVIS_SELECTED, "Unexpected old state %#x.\n", g_nmlistview.uOldState); + ok(g_nmlistview.uChanged == LVIF_STATE, "Unexpected change mask %#x.\n", g_nmlistview.uChanged); + + /* LVM_SETITEM changes state */ + memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview)); + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + item.mask = LVIF_STATE; + res = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item); + ok(res, "Failed to set item.\n"); + + ok(g_nmlistview.iItem == item.iItem, "Unexpected item %d.\n", g_nmlistview.iItem); + ok(g_nmlistview.iSubItem == item.iSubItem, "Unexpected subitem %d.\n", g_nmlistview.iSubItem); + ok(g_nmlistview.lParam == item.lParam, "Unexpected lParam.\n"); + ok(g_nmlistview.uNewState == LVIS_SELECTED, "Unexpected new state %#x.\n", g_nmlistview.uNewState); + ok(g_nmlistview.uOldState == 0, "Unexpected old state %#x.\n", g_nmlistview.uOldState); + ok(g_nmlistview.uChanged == LVIF_STATE, "Unexpected change mask %#x.\n", g_nmlistview.uChanged); + + /* LVM_SETITEM no state changes */ + memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview)); + memset(&item, 0, sizeof(item)); + item.lParam = 11; + item.mask = LVIF_PARAM; + res = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item); + ok(res, "Failed to set item.\n"); + + ok(g_nmlistview.iItem == item.iItem, "Unexpected item %d.\n", g_nmlistview.iItem); + ok(g_nmlistview.iSubItem == item.iSubItem, "Unexpected subitem %d.\n", g_nmlistview.iSubItem); + ok(g_nmlistview.lParam == item.lParam, "Unexpected lParam.\n"); + ok(g_nmlistview.uNewState == 0, "Unexpected new state %#x.\n", g_nmlistview.uNewState); + ok(g_nmlistview.uOldState == 0, "Unexpected old state %#x.\n", g_nmlistview.uOldState); + ok(g_nmlistview.uChanged == LVIF_PARAM, "Unexpected change mask %#x.\n", g_nmlistview.uChanged); + + DestroyWindow(hwnd); + } +} + START_TEST(listview) { ULONG_PTR ctx_cookie; @@ -6521,6 +6601,7 @@ START_TEST(listview) test_LVSCW_AUTOSIZE(); test_LVN_ENDLABELEDIT(); test_LVM_GETCOUNTPERPAGE(); + test_item_state_change();
if (!load_v6_module(&ctx_cookie, &hCtx)) { @@ -6565,6 +6646,7 @@ START_TEST(listview) test_LVSCW_AUTOSIZE(); test_LVN_ENDLABELEDIT(); test_LVM_GETCOUNTPERPAGE(); + test_item_state_change();
unload_v6_module(ctx_cookie, hCtx);