[PATCH 2/3] user32/tests: Test painting standard scroll bars in hovered state.

Zhiyi Zhang zzhang at codeweavers.com
Tue Jan 25 01:58:51 CST 2022


Mostly to test that standard scroll bars doesn't get painted in hovered state if they weren't
previously painted by DefWinProcA/W().

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/user32/tests/win.c | 122 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 0156987f529..ed90c5fbe5f 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -1132,12 +1132,42 @@ static void wine_AdjustWindowRectExForDpi( RECT *rect, LONG style, BOOL menu, LO
         InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
 }
 
+static int offset;
+
+static LRESULT CALLBACK test_standard_scrollbar_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+    switch (msg)
+    {
+    case WM_NCPAINT:
+    {
+        HRGN region;
+        RECT rect;
+
+        GetWindowRect(hwnd, &rect);
+        region = CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom - offset);
+        DefWindowProcA(hwnd, msg, (WPARAM)region, lp);
+        DeleteObject(region);
+        return 0;
+    }
+    default:
+        return DefWindowProcA(hwnd, msg, wp, lp);
+    }
+}
+
 static void test_nonclient_area(HWND hwnd)
 {
+    BOOL (WINAPI *pIsThemeActive)(void);
+    POINT point, old_cursor_pos;
+    COLORREF color, old_color;
+    BOOL is_theme_active;
     DWORD style, exstyle;
     RECT rc_window, rc_client, rc;
+    HWND child, parent;
+    HMODULE uxtheme;
+    WNDCLASSA cls;
     BOOL menu;
     LRESULT ret;
+    HDC hdc;
 
     style = GetWindowLongA(hwnd, GWL_STYLE);
     exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
@@ -1189,6 +1219,98 @@ static void test_nonclient_area(HWND hwnd)
     ok(EqualRect(&rc, &rc_client),
        "synthetic rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d, client=%s, calc=%s\n",
        style, exstyle, menu, wine_dbgstr_rect(&rc_client), wine_dbgstr_rect(&rc));
+
+    /* Test standard scroll bars */
+    uxtheme = LoadLibraryA("uxtheme.dll");
+    ok(!!uxtheme, "Failed to load uxtheme.dll, error %u.\n", GetLastError());
+    pIsThemeActive = (void *)GetProcAddress(uxtheme, "IsThemeActive");
+    ok(!!pIsThemeActive, "Failed to load IsThemeActive, error %u.\n", GetLastError());
+    is_theme_active = pIsThemeActive();
+
+    memset(&cls, 0, sizeof(cls));
+    cls.lpfnWndProc = DefWindowProcA;
+    cls.hInstance = GetModuleHandleA(0);
+    cls.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
+    cls.hbrBackground = GetStockObject(LTGRAY_BRUSH);
+    cls.lpszClassName = "TestStandardScrollbarParentClass";
+    RegisterClassA(&cls);
+
+    cls.lpfnWndProc = test_standard_scrollbar_proc;
+    cls.hbrBackground = GetStockObject(GRAY_BRUSH);
+    cls.lpszClassName = "TestStandardScrollbarClass";
+    RegisterClassA(&cls);
+
+    parent = CreateWindowA("TestStandardScrollbarParentClass", "parent", WS_POPUP | WS_VISIBLE, 100,
+                           100, 100, 100, NULL, NULL, 0, NULL);
+    ok(!!parent, "Failed to create a parent window, error %u.\n", GetLastError());
+    GetCursorPos(&old_cursor_pos);
+
+    /* Place the cursor on the standard scroll bar arrow button when not painting it at all.
+     * Expects the standard scroll bar not to appear before and after the cursor position change */
+    offset = GetSystemMetrics(SM_CYHSCROLL);
+    child = CreateWindowA("TestStandardScrollbarClass", "test", WS_CHILD | WS_HSCROLL | WS_VISIBLE,
+                          0, 0, 50, 50, parent, NULL, 0, NULL);
+    ok(!!child, "Failed to create a test window, error %u.\n", GetLastError());
+    hdc = GetDC(parent);
+    ok(!!hdc, "GetDC failed, error %d.\n", GetLastError());
+
+    SetCursorPos(0, 0);
+    flush_events(TRUE);
+    RedrawWindow(child, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ERASENOW | RDW_FRAME);
+    old_color = GetPixel(hdc, 50 - GetSystemMetrics(SM_CXVSCROLL) / 2,
+                         50 - GetSystemMetrics(SM_CYHSCROLL) / 2);
+    ok(old_color == 0xc0c0c0, "Expected color %#x, got %#x.\n", 0xc0c0c0, old_color);
+
+    point.x = 50 - GetSystemMetrics(SM_CXVSCROLL) / 2;
+    point.y = 50 - GetSystemMetrics(SM_CYHSCROLL) / 2;
+    ClientToScreen(child, &point);
+    SetCursorPos(point.x, point.y);
+    flush_events(TRUE);
+    RedrawWindow(child, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ERASENOW | RDW_FRAME);
+    color = GetPixel(hdc, 50 - GetSystemMetrics(SM_CXVSCROLL) / 2,
+                     50 - GetSystemMetrics(SM_CYHSCROLL) / 2);
+    todo_wine
+    ok(color == old_color, "Expected color %#x, got %#x.\n", old_color, color);
+
+    ReleaseDC(parent, hdc);
+    DestroyWindow(child);
+
+    /* Place the cursor on standard scroll bar arrow button when painting 1 pixel of the scroll bar.
+     * Expects the scroll bar to appear after the cursor position change */
+    offset = GetSystemMetrics(SM_CYHSCROLL) - 1;
+    child = CreateWindowA("TestStandardScrollbarClass", "test", WS_CHILD | WS_HSCROLL | WS_VISIBLE,
+                          0, 0, 50, 50, parent, NULL, 0, NULL);
+    ok(!!child, "Failed to create a test window, error %u.\n", GetLastError());
+    hdc = GetDC(parent);
+    ok(!!hdc, "GetDC failed, error %d.\n", GetLastError());
+
+    SetCursorPos(0, 0);
+    flush_events(TRUE);
+    RedrawWindow(child, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ERASENOW | RDW_FRAME);
+    old_color = GetPixel(hdc, 50 - GetSystemMetrics(SM_CXVSCROLL) / 2,
+                         50 - GetSystemMetrics(SM_CYHSCROLL) / 2);
+
+    point.x = 50 - GetSystemMetrics(SM_CXVSCROLL) / 2;
+    point.y = 50 - GetSystemMetrics(SM_CYHSCROLL) / 2;
+    ClientToScreen(child, &point);
+    SetCursorPos(point.x, point.y);
+    flush_events(TRUE);
+    RedrawWindow(child, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ERASENOW | RDW_FRAME);
+    color = GetPixel(hdc, 50 - GetSystemMetrics(SM_CXVSCROLL) / 2,
+                     50 - GetSystemMetrics(SM_CYHSCROLL) / 2);
+    if (is_theme_active)
+        ok(color != old_color || broken(color == old_color), /* Win 10 1507 64-bit */
+           "Got unexpected color %#x.\n", color);
+    else
+        todo_wine
+        ok(color == old_color, "Expected color %#x, got %#x.\n", old_color, color);
+
+    SetCursorPos(old_cursor_pos.x, old_cursor_pos.y);
+    ReleaseDC(parent, hdc);
+    DestroyWindow(parent);
+    UnregisterClassA("TestStandardScrollbarClass", GetModuleHandleA(0));
+    UnregisterClassA("TestStandardScrollbarParentClass", GetModuleHandleA(0));
+    FreeLibrary(uxtheme);
 }
 
 static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam) 
-- 
2.32.0




More information about the wine-devel mailing list