Based on simliar patch for comctl32/treeview: 231199bc46
WM_PRINTCLIENT paints the items of a listview, including the item backgrounds, but never the listview background.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54878 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55005 Co-authored-by: Alex Henrie alexhenrie24@gmail.com
-- v2: comctl32/listview: Ignore the lParam to WM_PRINTCLIENT and add tests.
From: Bernhard Übelacker bernhardu@mailbox.org
Based on simliar patch for comctl32/treeview: 231199bc46
WM_PRINTCLIENT paints the items of a listview, including the item backgrounds, but never the listview background.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54878 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55005 Co-authored-by: Alex Henrie alexhenrie24@gmail.com --- dlls/comctl32/listview.c | 12 +---- dlls/comctl32/tests/listview.c | 96 ++++++++++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 15 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 7972be9669d..c82473b6205 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -10832,17 +10832,9 @@ static inline LRESULT LISTVIEW_WMPaint(LISTVIEW_INFO *infoPtr, HDC hdc) */ static LRESULT LISTVIEW_PrintClient(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD options) { - if ((options & PRF_CHECKVISIBLE) && !IsWindowVisible(infoPtr->hwndSelf)) - return 0; - - if (options & ~(PRF_ERASEBKGND|PRF_CLIENT)) - FIXME("(hdc=%p options %#lx) partial stub\n", hdc, options); - - if (options & PRF_ERASEBKGND) - LISTVIEW_EraseBkgnd(infoPtr, hdc); + FIXME("(hdc=%p options=%#lx) partial stub\n", hdc, options);
- if (options & PRF_CLIENT) - LISTVIEW_Paint(infoPtr, hdc); + LISTVIEW_Paint(infoPtr, hdc);
return 0; } diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index b1cb0ef16c2..59217c966f6 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -25,10 +25,16 @@ #include <commctrl.h> #include <objbase.h>
+#include "uxtheme.h" +#include "vsstyle.h" + #include "wine/test.h" #include "v6util.h" #include "msg.h"
+static HTHEME (WINAPI *pGetWindowTheme)(HWND); +static BOOL (WINAPI *pIsThemeBackgroundPartiallyTransparent)(HTHEME, int, int); + static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int); static BOOL (WINAPI *pImageList_Destroy)(HIMAGELIST); static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP); @@ -90,12 +96,16 @@ static HWND subclass_editbox(HWND hwndListview); static void init_functions(void) { HMODULE hComCtl32 = LoadLibraryA("comctl32.dll"); + HMODULE hUxtheme = LoadLibraryA("uxtheme.dll"); + +#define X(module, f) p##f = (void*)GetProcAddress(module, #f); + X(hComCtl32, ImageList_Create); + X(hComCtl32, ImageList_Destroy); + X(hComCtl32, ImageList_Add); + X(hComCtl32, _TrackMouseEvent);
-#define X(f) p##f = (void*)GetProcAddress(hComCtl32, #f); - X(ImageList_Create); - X(ImageList_Destroy); - X(ImageList_Add); - X(_TrackMouseEvent); + X(hUxtheme, GetWindowTheme); + X(hUxtheme, IsThemeBackgroundPartiallyTransparent); #undef X }
@@ -5978,6 +5988,80 @@ static void test_LVM_REDRAWITEMS(void) DestroyWindow(list); }
+static void test_WM_PRINTCLIENT(void) +{ + static const LPARAM params[] = {0, PRF_CHECKVISIBLE, PRF_NONCLIENT, PRF_CLIENT, PRF_ERASEBKGND, + PRF_CHILDREN, PRF_OWNED}; + const DWORD list_background = RGB(255, 0, 0); + const DWORD text_background = RGB(0, 0, 255); + BOOL listitem_is_transparent; + HTHEME hTheme; + HWND hList; + COLORREF clr; + LONG ret; + RECT rc; + HDC hdc; + int i; + + hList = create_listview_control(LVS_LIST); + insert_item(hList, 0); + + ret = SendMessageA(hList, LVM_SETBKCOLOR, 0, list_background); + ok(ret == TRUE, "got 0x%lx, expected 0x%x\n", ret, TRUE); + + ret = SendMessageA(hList, LVM_SETTEXTBKCOLOR, 0, text_background); + ok(ret == TRUE, "got 0x%lx, expected 0x%x\n", ret, TRUE); + + hdc = GetDC(hwndparent); + GetClientRect(hwndparent, &rc); + + hTheme = pGetWindowTheme(hList); + listitem_is_transparent = hTheme && pIsThemeBackgroundPartiallyTransparent(hTheme, LVP_LISTITEM, 0); + + /* test parameters when the listview is visible */ + for (i = 0; i < ARRAY_SIZE(params); i++) + { + winetest_push_context("lParam=0x%Ix", params[i]); + FillRect(hdc, &rc, GetStockObject(BLACK_BRUSH)); + clr = GetPixel(hdc, 1, 1); + ok(clr == RGB(0, 0, 0), "got 0x%lx\n", clr); + clr = GetPixel(hdc, 50, 1); + ok(clr == RGB(0, 0, 0), "got 0x%lx\n", clr); + ret = SendMessageA(hList, WM_PRINTCLIENT, (WPARAM)hdc, params[i]); + ok(ret == 0, "got %ld\n", ret); + clr = GetPixel(hdc, 1, 1); + ok(clr == text_background || (listitem_is_transparent && clr == list_background), + "got 0x%lx\n", clr); + clr = GetPixel(hdc, 50, 1); + ok(clr == RGB(0, 0, 0), "got 0x%lx\n", clr); + winetest_pop_context(); + } + + /* test parameters when the listview is hidden */ + ShowWindow(hList, SW_HIDE); + for (i = 0; i < ARRAY_SIZE(params); i++) + { + winetest_push_context("lParam=0x%Ix", params[i]); + FillRect(hdc, &rc, GetStockObject(BLACK_BRUSH)); + clr = GetPixel(hdc, 1, 1); + ok(clr == RGB(0, 0, 0), "got 0x%lx\n", clr); + clr = GetPixel(hdc, 50, 1); + ok(clr == RGB(0, 0, 0), "got 0x%lx\n", clr); + ret = SendMessageA(hList, WM_PRINTCLIENT, (WPARAM)hdc, params[i]); + ok(ret == 0, "got %ld\n", ret); + clr = GetPixel(hdc, 1, 1); + ok(clr == text_background || (listitem_is_transparent && clr == list_background), + "got 0x%lx\n", clr); + clr = GetPixel(hdc, 50, 1); + ok(clr == RGB(0, 0, 0), "got 0x%lx\n", clr); + winetest_pop_context(); + } + ShowWindow(hList, SW_SHOW); + + ReleaseDC(hwndparent, hdc); + DestroyWindow(hList); +} + static void test_imagelists(void) { HWND hwnd, header; @@ -7153,6 +7237,7 @@ START_TEST(listview) test_dispinfo(); test_LVM_SETITEMTEXT(); test_LVM_REDRAWITEMS(); + test_WM_PRINTCLIENT(); test_imagelists(); test_deleteitem(); test_insertitem(); @@ -7205,6 +7290,7 @@ START_TEST(listview) test_dispinfo(); test_LVM_SETITEMTEXT(); test_LVM_REDRAWITEMS(); + test_WM_PRINTCLIENT(); test_oneclickactivate(); test_state_image(); test_LVSCW_AUTOSIZE();
On Wed Dec 13 10:43:30 2023 +0000, Nikolay Sivov wrote:
There is, we have two sections, running most of the same tests twice. One before context activation, and one with active context that enables new module.
You asked about comctl32 v5, but since test_WM_PRINTCLIENT also passes on v6, I've pushed a new patch that calls it in the v6 section too.
Zhiyi Zhang (@zhiyi) commented about dlls/comctl32/tests/listview.c:
- ret = SendMessageA(hList, LVM_SETBKCOLOR, 0, list_background);
- ok(ret == TRUE, "got 0x%lx, expected 0x%x\n", ret, TRUE);
- ret = SendMessageA(hList, LVM_SETTEXTBKCOLOR, 0, text_background);
- ok(ret == TRUE, "got 0x%lx, expected 0x%x\n", ret, TRUE);
- hdc = GetDC(hwndparent);
- GetClientRect(hwndparent, &rc);
- hTheme = pGetWindowTheme(hList);
- listitem_is_transparent = hTheme && pIsThemeBackgroundPartiallyTransparent(hTheme, LVP_LISTITEM, 0);
- /* test parameters when the listview is visible */
- for (i = 0; i < ARRAY_SIZE(params); i++)
- {
winetest_push_context("lParam=0x%Ix", params[i]);
I prefer a newline after winetest_push_context() and before winetest_pop_context().
Zhiyi Zhang (@zhiyi) commented about dlls/comctl32/tests/listview.c:
ok(clr == RGB(0, 0, 0), "got 0x%lx\n", clr);
ret = SendMessageA(hList, WM_PRINTCLIENT, (WPARAM)hdc, params[i]);
ok(ret == 0, "got %ld\n", ret);
clr = GetPixel(hdc, 1, 1);
ok(clr == text_background || (listitem_is_transparent && clr == list_background),
"got 0x%lx\n", clr);
clr = GetPixel(hdc, 50, 1);
ok(clr == RGB(0, 0, 0), "got 0x%lx\n", clr);
winetest_pop_context();
- }
- /* test parameters when the listview is hidden */
- ShowWindow(hList, SW_HIDE);
- for (i = 0; i < ARRAY_SIZE(params); i++)
- {
winetest_push_context("lParam=0x%Ix", params[i]);
These two loops look identical. Could you merge them into a new loop? For example, states = {SW_HIDE, SW_SHOW}; for (i = 0; i < ARRAY_SIZE(states); i++);