Comctl32 v5 listview sets the initial background mix mode to TRANSPARENT. Comctl32 v6 listview sets it to OPAQUE. Use TRANSPARENT for both v5 and v6 for now.
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/comctl32/tests/listview.c | 104 ++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 40 deletions(-)
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index b767106e97a..386fde36939 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -2083,6 +2083,7 @@ static void test_redraw(void) static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { COLORREF clr, c0ffee = RGB(0xc0, 0xff, 0xee); + int mode;
if(message == WM_NOTIFY) { NMHDR *nmhdr = (NMHDR*)lParam; @@ -2102,9 +2103,15 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
switch(nmlvcd->nmcd.dwDrawStage) { case CDDS_PREPAINT: + mode = GetBkMode(nmlvcd->nmcd.hdc); + todo_wine + ok(mode == TRANSPARENT, "Got unexpected mode.\n"); SetBkColor(nmlvcd->nmcd.hdc, c0ffee); return CDRF_NOTIFYITEMDRAW|CDRF_NOTIFYPOSTPAINT; case CDDS_ITEMPREPAINT: + mode = GetBkMode(nmlvcd->nmcd.hdc); + todo_wine + ok(mode == TRANSPARENT, "Got unexpected mode.\n"); clr = GetBkColor(nmlvcd->nmcd.hdc); todo_wine_if(nmlvcd->iSubItem) ok(clr == c0ffee, "Unexpected background color %#lx.\n", clr); @@ -2112,6 +2119,9 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM nmlvcd->clrText = RGB(0, 255, 0); return CDRF_NOTIFYSUBITEMDRAW|CDRF_NOTIFYPOSTPAINT; case CDDS_ITEMPREPAINT | CDDS_SUBITEM: + mode = GetBkMode(nmlvcd->nmcd.hdc); + todo_wine + ok(mode == TRANSPARENT, "Got unexpected mode.\n"); clr = GetBkColor(nmlvcd->nmcd.hdc); ok(nmlvcd->clrTextBk == CLR_DEFAULT, "Unexpected text background %#lx.\n", nmlvcd->clrTextBk); ok(nmlvcd->clrText == RGB(0, 255, 0), "Unexpected text color %#lx.\n", nmlvcd->clrText); @@ -2122,6 +2132,9 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM ok(clr == c0ffee, "clr=%.8lx\n", clr); return CDRF_NOTIFYPOSTPAINT; case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM: + mode = GetBkMode(nmlvcd->nmcd.hdc); + todo_wine + ok(mode == TRANSPARENT, "Got unexpected mode.\n"); clr = GetBkColor(nmlvcd->nmcd.hdc); if (showsel_always && is_selected) ok(clr == GetSysColor(COLOR_3DFACE), "Unexpected background color %#lx.\n", clr); @@ -2144,62 +2157,73 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
static void test_customdraw(void) { + static const COLORREF test_colors[] = {CLR_DEFAULT, CLR_NONE, RGB(255, 0, 0)}; HWND hwnd; WNDPROC oldwndproc; LVITEMA item; + int i;
- hwnd = create_listview_control(LVS_REPORT); + for (i = 0; i < ARRAY_SIZE(test_colors); i++) + { + winetest_push_context("color %#x", i);
- insert_column(hwnd, 0); - insert_column(hwnd, 1); - insert_item(hwnd, 0); + hwnd = create_listview_control(LVS_REPORT);
- oldwndproc = (WNDPROC)SetWindowLongPtrA(hwndparent, GWLP_WNDPROC, - (LONG_PTR)cd_wndproc); + insert_column(hwnd, 0); + insert_column(hwnd, 1); + insert_item(hwnd, 0); + SendMessageA(hwnd, LVM_SETTEXTBKCOLOR, 0, test_colors[i]);
- InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); + oldwndproc = (WNDPROC)SetWindowLongPtrA(hwndparent, GWLP_WNDPROC, + (LONG_PTR)cd_wndproc);
- /* message tests */ - 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", FALSE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd);
- /* Check colors when item is selected. */ - item.mask = LVIF_STATE; - item.stateMask = LVIS_SELECTED; - item.state = LVIS_SELECTED; - SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + /* message tests */ + 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", FALSE);
- 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, item selected, LVS_REPORT, selection", FALSE); + /* Check colors when item is selected. */ + item.mask = LVIF_STATE; + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
- SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) | LVS_SHOWSELALWAYS); - 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, item selected, LVS_SHOWSELALWAYS, LVS_REPORT", FALSE); + 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, item selected, LVS_REPORT, selection", FALSE);
- DestroyWindow(hwnd); + SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) | LVS_SHOWSELALWAYS); + 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, item selected, LVS_SHOWSELALWAYS, LVS_REPORT", FALSE);
- hwnd = create_listview_control(LVS_LIST); + DestroyWindow(hwnd);
- insert_column(hwnd, 0); - insert_column(hwnd, 1); - insert_item(hwnd, 0); + hwnd = create_listview_control(LVS_LIST);
- flush_sequences(sequences, NUM_MSG_SEQUENCES); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_list_cd_seq, "parent customdraw, LVS_LIST", FALSE); + insert_column(hwnd, 0); + insert_column(hwnd, 1); + insert_item(hwnd, 0); + SendMessageA(hwnd, LVM_SETTEXTBKCOLOR, 0, test_colors[i]);
- SetWindowLongPtrA(hwndparent, GWLP_WNDPROC, (LONG_PTR)oldwndproc); - DestroyWindow(hwnd); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_list_cd_seq, "parent customdraw, LVS_LIST", FALSE); + + SetWindowLongPtrA(hwndparent, GWLP_WNDPROC, (LONG_PTR)oldwndproc); + DestroyWindow(hwnd); + + winetest_pop_context(); + } }
static void test_icon_spacing(void)
From: Zhiyi Zhang zzhang@codeweavers.com
Comctl32 v5 listview sets the initial background mix mode to TRANSPARENT. Comctl32 v6 listview sets it to OPAQUE. Use TRANSPARENT for both v5 and v6 for now. --- dlls/comctl32/listview.c | 10 +++------- dlls/comctl32/tests/listview.c | 4 ---- 2 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 31f8a933e56..c5709cf2a4b 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -1120,13 +1120,7 @@ static void prepaint_setup (const LISTVIEW_INFO *infoPtr, HDC hdc, const NMLVCUS textcolor = comctl32_color.clrWindowText;
/* Set the text attributes */ - if (backcolor != CLR_NONE) - { - SetBkMode(hdc, OPAQUE); - SetBkColor(hdc, backcolor); - } - else - SetBkMode(hdc, TRANSPARENT); + SetBkColor(hdc, backcolor); SetTextColor(hdc, textcolor); }
@@ -5271,6 +5265,8 @@ static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc, const RECT *prcEra
GetClientRect(infoPtr->hwndSelf, &rcClient); customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient, 0); + /* v5 sets the initial background mix mode to TRANSPARENT while v6 uses OPAQUE. */ + SetBkMode(hdc, TRANSPARENT); cdmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd); if (cdmode & CDRF_SKIPDEFAULT) goto enddraw;
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 386fde36939..bf5afd694c3 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -2104,13 +2104,11 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM switch(nmlvcd->nmcd.dwDrawStage) { case CDDS_PREPAINT: mode = GetBkMode(nmlvcd->nmcd.hdc); - todo_wine ok(mode == TRANSPARENT, "Got unexpected mode.\n"); SetBkColor(nmlvcd->nmcd.hdc, c0ffee); return CDRF_NOTIFYITEMDRAW|CDRF_NOTIFYPOSTPAINT; case CDDS_ITEMPREPAINT: mode = GetBkMode(nmlvcd->nmcd.hdc); - todo_wine ok(mode == TRANSPARENT, "Got unexpected mode.\n"); clr = GetBkColor(nmlvcd->nmcd.hdc); todo_wine_if(nmlvcd->iSubItem) @@ -2120,7 +2118,6 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM return CDRF_NOTIFYSUBITEMDRAW|CDRF_NOTIFYPOSTPAINT; case CDDS_ITEMPREPAINT | CDDS_SUBITEM: mode = GetBkMode(nmlvcd->nmcd.hdc); - todo_wine ok(mode == TRANSPARENT, "Got unexpected mode.\n"); clr = GetBkColor(nmlvcd->nmcd.hdc); ok(nmlvcd->clrTextBk == CLR_DEFAULT, "Unexpected text background %#lx.\n", nmlvcd->clrTextBk); @@ -2133,7 +2130,6 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM return CDRF_NOTIFYPOSTPAINT; case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM: mode = GetBkMode(nmlvcd->nmcd.hdc); - todo_wine ok(mode == TRANSPARENT, "Got unexpected mode.\n"); clr = GetBkColor(nmlvcd->nmcd.hdc); if (showsel_always && is_selected)
Nikolay Sivov (@nsivov) commented about dlls/comctl32/listview.c:
GetClientRect(infoPtr->hwndSelf, &rcClient); customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient, 0);
- /* v5 sets the initial background mix mode to TRANSPARENT while v6 uses OPAQUE. */
- SetBkMode(hdc, TRANSPARENT); cdmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd); if (cdmode & CDRF_SKIPDEFAULT) goto enddraw;
I don't think we can do that unconditionally, a lot of application were never tested with v5 and very likely depend on such differences. I know that we don't run some of the painting tests on v6 at the moment. Splitting them up and having a separate test for background mode that runs on v5 and v6 is what we should do.
We might do a separate v6 build in theory, but I suspect that will be avoided for as long as possible. It should be enough to check for windows class in current context in WM_NCCREATE (and maybe for actual class name too if it's possible to use versioned name directly, I don't remember).