[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