Module: wine Branch: master Commit: 13dfb9b3a6c05c0e6dfe5d6d55cd410e83edea36 URL: http://source.winehq.org/git/wine.git/?a=commit;h=13dfb9b3a6c05c0e6dfe5d6d55...
Author: Nikolay Sivov bunglehead@gmail.com Date: Thu Apr 9 17:23:01 2009 -0400
comctl32/listview: State mask should be ignored on LVM_INSERTITEM.
---
dlls/comctl32/listview.c | 18 ++++++----- dlls/comctl32/tests/listview.c | 66 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 8 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index f06095b..e571f33 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -3478,6 +3478,8 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL NMLISTVIEW nmlv; UINT uChanged = 0; LVITEMW item; + /* stateMask is ignored for LVM_INSERTITEM */ + UINT stateMask = isNew ? ~0 : lpLVItem->stateMask;
TRACE("()\n");
@@ -3510,7 +3512,7 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
TRACE("oldState=%x, newState=%x\n", item.state, lpLVItem->state); /* determine what fields will change */ - if ((lpLVItem->mask & LVIF_STATE) && ((item.state ^ lpLVItem->state) & lpLVItem->stateMask & ~infoPtr->uCallbackMask)) + if ((lpLVItem->mask & LVIF_STATE) && ((item.state ^ lpLVItem->state) & stateMask & ~infoPtr->uCallbackMask)) uChanged |= LVIF_STATE;
if ((lpLVItem->mask & LVIF_IMAGE) && (lpItem->hdr.iImage != lpLVItem->iImage)) @@ -3531,7 +3533,7 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
ZeroMemory(&nmlv, sizeof(NMLISTVIEW)); nmlv.iItem = lpLVItem->iItem; - nmlv.uNewState = (item.state & ~lpLVItem->stateMask) | (lpLVItem->state & lpLVItem->stateMask); + nmlv.uNewState = (item.state & ~stateMask) | (lpLVItem->state & stateMask); nmlv.uOldState = item.state; nmlv.uChanged = uChanged; nmlv.lParam = item.lParam; @@ -3564,21 +3566,21 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
if (uChanged & LVIF_STATE) { - if (lpItem && (lpLVItem->stateMask & ~infoPtr->uCallbackMask & ~(LVIS_FOCUSED | LVIS_SELECTED))) + if (lpItem && (stateMask & ~infoPtr->uCallbackMask & ~(LVIS_FOCUSED | LVIS_SELECTED))) { - lpItem->state &= ~lpLVItem->stateMask; - lpItem->state |= (lpLVItem->state & lpLVItem->stateMask); + lpItem->state &= ~stateMask; + lpItem->state |= (lpLVItem->state & stateMask); } - if (lpLVItem->state & lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED) + if (lpLVItem->state & stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED) { if (infoPtr->dwStyle & LVS_SINGLESEL) LISTVIEW_DeselectAllSkipItem(infoPtr, lpLVItem->iItem); ranges_additem(infoPtr->selectionRanges, lpLVItem->iItem); } - else if (lpLVItem->stateMask & LVIS_SELECTED) + else if (stateMask & LVIS_SELECTED) ranges_delitem(infoPtr->selectionRanges, lpLVItem->iItem); /* if we are asked to change focus, and we manage it, do it */ - if (lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED) + if (stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED) { if (lpLVItem->state & LVIS_FOCUSED) { diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 6f3524b..914be42 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -634,6 +634,72 @@ static void test_items(void) insert_column(hwnd, 0); insert_column(hwnd, 1);
+ /* LVIS_SELECTED with zero stateMask */ + /* set */ + memset (&item, 0, sizeof (item)); + item.mask = LVIF_STATE; + item.state = LVIS_SELECTED; + item.stateMask = 0; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); + ok(r == 0, "ret %d\n", r); + /* get */ + memset (&item, 0xcc, sizeof (item)); + item.mask = LVIF_STATE; + item.stateMask = LVIS_SELECTED; + item.state = 0; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + ok(r != 0, "ret %d\n", r); + ok(item.state & LVIS_SELECTED, "Expected LVIS_SELECTED\n"); + SendMessage(hwnd, LVM_DELETEITEM, 0, 0); + + /* LVIS_SELECTED with zero stateMask */ + /* set */ + memset (&item, 0, sizeof (item)); + item.mask = LVIF_STATE; + item.state = LVIS_FOCUSED; + item.stateMask = 0; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); + ok(r == 0, "ret %d\n", r); + /* get */ + memset (&item, 0xcc, sizeof (item)); + item.mask = LVIF_STATE; + item.stateMask = LVIS_FOCUSED; + item.state = 0; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + ok(r != 0, "ret %d\n", r); + ok(item.state & LVIS_FOCUSED, "Expected LVIS_FOCUSED\n"); + SendMessage(hwnd, LVM_DELETEITEM, 0, 0); + + /* LVIS_CUT with LVIS_FOCUSED stateMask */ + /* set */ + memset (&item, 0, sizeof (item)); + item.mask = LVIF_STATE; + item.state = LVIS_CUT; + item.stateMask = LVIS_FOCUSED; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); + ok(r == 0, "ret %d\n", r); + /* get */ + memset (&item, 0xcc, sizeof (item)); + item.mask = LVIF_STATE; + item.stateMask = LVIS_CUT; + item.state = 0; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + ok(r != 0, "ret %d\n", r); + ok(item.state & LVIS_CUT, "Expected LVIS_CUT\n"); + SendMessage(hwnd, LVM_DELETEITEM, 0, 0); + /* Insert an item with just a param */ memset (&item, 0xcc, sizeof (item)); item.mask = LVIF_PARAM;