From: Vijay Kiran Kamuju Subject: [PATCH 1/2] comctl32: Preserve custom colors between subitems. (v2) Message-Id: <20191209162005.602-1-infyquest@gmail.com> Date: Mon, 9 Dec 2019 17:20:04 +0100 From: Michael Müller From: Michael Müller Signed-off-by: Vijay Kiran Kamuju Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38941 --- dlls/comctl32/listview.c | 20 +++++++++----------- dlls/comctl32/tests/listview.c | 23 ++++++++++++++++++++--- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index eb42526f57..4799920e3a 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -1065,7 +1065,7 @@ static void prepaint_setup (const LISTVIEW_INFO *infoPtr, HDC hdc, NMLVCUSTOMDRA COLORREF backcolor, textcolor; /* apparently, for selected items, we have to override the returned values */ - if (!SubItem) + if (!SubItem || (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) { if (lpnmlvcd->nmcd.uItemState & CDIS_SELECTED) { @@ -4791,6 +4791,7 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, ITERAT while (iterator_next(subitems)) { DWORD subitemstage = CDRF_DODEFAULT; + NMLVCUSTOMDRAW temp_nmlvcd; /* We need to query for each subitem, item's data (subitem == 0) is already here at this point */ if (subitems->nItem) @@ -4817,19 +4818,16 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, ITERAT if (cdsubitemmode & CDRF_NOTIFYSUBITEMDRAW) subitemstage = notify_customdraw(infoPtr, CDDS_SUBITEM | CDDS_ITEMPREPAINT, &nmlvcd); - else - { - nmlvcd.clrTextBk = infoPtr->clrTextBk; - nmlvcd.clrText = infoPtr->clrText; - } - if (subitems->nItem == 0 || (cdmode & CDRF_NOTIFYITEMDRAW)) - prepaint_setup(infoPtr, hdc, &nmlvcd, FALSE); - else if (!(infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) - prepaint_setup(infoPtr, hdc, &nmlvcd, TRUE); + /* + * A selection should neither affect the colors in the post paint notification nor + * affect the colors of the next drawn subitem. Copy the structure to prevent this. + */ + temp_nmlvcd = nmlvcd; + prepaint_setup(infoPtr, hdc, &temp_nmlvcd, subitems->nItem); if (!(subitemstage & CDRF_SKIPDEFAULT)) - LISTVIEW_DrawItemPart(infoPtr, &lvItem, &nmlvcd, &pos); + LISTVIEW_DrawItemPart(infoPtr, &lvItem, &temp_nmlvcd, &pos); if (subitemstage & CDRF_NOTIFYPOSTPAINT) subitemstage = notify_customdraw(infoPtr, CDDS_SUBITEM | CDDS_ITEMPOSTPAINT, &nmlvcd); diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 87f644abd1..57cb227189 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -1938,12 +1938,16 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM clr = GetBkColor(nmlvcd->nmcd.hdc); ok(nmlvcd->clrTextBk == CLR_DEFAULT, "got 0x%x\n", nmlvcd->clrTextBk); ok(nmlvcd->clrText == RGB(0, 255, 0), "got 0x%x\n", nmlvcd->clrText); - todo_wine_if(nmlvcd->iSubItem) - ok(clr == c0ffee, "clr=%.8x\n", clr); + if (!(GetWindowLongW(nmhdr->hwndFrom, GWL_STYLE) & LVS_SHOWSELALWAYS)) + { + todo_wine_if(nmlvcd->iSubItem) + ok(clr == c0ffee, "clr=%.8x\n", clr); + } return CDRF_NOTIFYPOSTPAINT; case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM: clr = GetBkColor(nmlvcd->nmcd.hdc); - todo_wine ok(clr == c0ffee, "clr=%.8x\n", clr); + if (!(GetWindowLongW(nmhdr->hwndFrom, GWL_STYLE) & LVS_SHOWSELALWAYS)) + todo_wine ok(clr == c0ffee, "clr=%.8x\n", clr); ok(nmlvcd->clrTextBk == CLR_DEFAULT, "got 0x%x\n", nmlvcd->clrTextBk); ok(nmlvcd->clrText == RGB(0, 255, 0), "got 0x%x\n", nmlvcd->clrText); return CDRF_DODEFAULT; @@ -1959,6 +1963,7 @@ static void test_customdraw(void) { HWND hwnd; WNDPROC oldwndproc; + LVITEMA item; hwnd = create_listview_control(LVS_REPORT); @@ -1978,6 +1983,18 @@ static void test_customdraw(void) UpdateWindow(hwnd); ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_report_cd_seq, "parent customdraw, LVS_REPORT", FALSE); + /* check colors when item is selected */ + SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) | LVS_SHOWSELALWAYS); + item.mask = LVIF_STATE; + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_report_cd_seq, "parent customdraw, LVS_REPORT, selection", FALSE); + DestroyWindow(hwnd); hwnd = create_listview_control(LVS_LIST); -- 2.21.0