[4/5] comctl32/listview: Fix a regression caused by 9c1a0e468f5cfbe9d863852ed5a42390f2cbfeb4 (try2)

Nikolay Sivov bunglehead at gmail.com
Mon Apr 20 07:21:29 CDT 2009


Commit 9c1a0e468f5cfbe9d863852ed5a42390f2cbfeb4 introduced a regression
for LVS_OWNERDATA style - crash after item state changing.
NULL pointer used fot LVS_OWNERDATA case. Since now we're storing
LVIS_FOCUSED and LVIS_SELECTED sates move state storing at a single place.

Changelog:
    - try2: basic set selection test added
    - Fix regression caused by 9c1a0e468f5cfbe9d863852ed5a42390f2cbfeb4

>From dd1bbd05e05a02ddce3381423ea5c407513cc5a4 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Mon, 20 Apr 2009 08:03:07 -0400
Subject: Fix a regression caused by 9c1a0e468f5cfbe9d863852ed5a42390f2cbfeb4

---
 dlls/comctl32/listview.c       |    6 +-----
 dlls/comctl32/tests/listview.c |   18 ++++++++++++++++++
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index 870354c..d249cff 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -3565,7 +3565,7 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
 
     if (uChanged & LVIF_STATE)
     {
-	if (lpItem && (stateMask & ~infoPtr->uCallbackMask & ~(LVIS_FOCUSED | LVIS_SELECTED)))
+	if (lpItem && (stateMask & ~infoPtr->uCallbackMask))
 	{
 	    lpItem->state &= ~stateMask;
 	    lpItem->state |= (lpLVItem->state & stateMask);
@@ -3574,12 +3574,10 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
 	{
 	    if (infoPtr->dwStyle & LVS_SINGLESEL) LISTVIEW_DeselectAllSkipItem(infoPtr, lpLVItem->iItem);
 	    ranges_additem(infoPtr->selectionRanges, lpLVItem->iItem);
-	    lpItem->state |= LVIS_SELECTED;
 	}
 	else if (stateMask & LVIS_SELECTED)
 	{
 	    ranges_delitem(infoPtr->selectionRanges, lpLVItem->iItem);
-	    lpItem->state &= ~LVIS_SELECTED;
 	}
 	/* if we are asked to change focus, and we manage it, do it */
 	if (stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED)
@@ -3597,13 +3595,11 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
 		    LISTVIEW_SetItemState(infoPtr, infoPtr->nFocusedItem, &item);
 		}
 
-		lpItem->state |= LVIS_FOCUSED;
 		infoPtr->nFocusedItem = lpLVItem->iItem;
     	        LISTVIEW_EnsureVisible(infoPtr, lpLVItem->iItem, uView == LVS_LIST);
 	    }
 	    else if (infoPtr->nFocusedItem == lpLVItem->iItem)
 	    {
-	        lpItem->state &= ~LVIS_FOCUSED;
 	        infoPtr->nFocusedItem = -1;
 	    }
 	}
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index 5aa2f52..5733668 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -1532,6 +1532,8 @@ static void test_ownerdata(void)
 {
     HWND hwnd;
     LONG_PTR style, ret;
+    DWORD res;
+    LVITEMA item;
 
     /* it isn't possible to set LVS_OWNERDATA after creation */
     hwnd = create_listview_control(0);
@@ -1579,6 +1581,22 @@ static void test_ownerdata(void)
     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
     ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
     DestroyWindow(hwnd);
+
+    /* try select an item */
+    hwnd = create_listview_control(LVS_OWNERDATA);
+    ok(hwnd != NULL, "failed to create a listview window\n");
+    res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
+    ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n");
+    res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
+    expect(0, res);
+    memset(&item, 0, sizeof(item));
+    item.stateMask = LVIS_SELECTED;
+    item.state     = LVIS_SELECTED;
+    res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
+    expect(TRUE, res);
+    res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
+    expect(1, res);
+    DestroyWindow(hwnd);
 }
 
 START_TEST(listview)
-- 
1.5.6.5





More information about the wine-patches mailing list