[PATCH v3] comctl32/listview: Don't report current item state in change notification when state change wasn't requested.

Nikolay Sivov nsivov at codeweavers.com
Wed Aug 14 01:42:58 CDT 2019


From: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 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 2717812d0b..acf6f31fe6 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 48612db54f..48cd614380 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);
 
-- 
2.23.0.rc1




More information about the wine-devel mailing list