From: Zhiyi Zhang zzhang@codeweavers.com
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/uxtheme/tests/system.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index 1f04ac879ec..f169231b214 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -40,6 +40,7 @@ static HTHEME (WINAPI * pOpenThemeDataEx)(HWND, LPCWSTR, DWORD); static HTHEME (WINAPI *pOpenThemeDataForDpi)(HWND, LPCWSTR, UINT); static HPAINTBUFFER (WINAPI *pBeginBufferedPaint)(HDC, const RECT *, BP_BUFFERFORMAT, BP_PAINTPARAMS *, HDC *); static HRESULT (WINAPI *pBufferedPaintClear)(HPAINTBUFFER, const RECT *); +static HRESULT (WINAPI *pDrawThemeBackgroundEx)(HTHEME, HDC, int, int, const RECT *, const DTBGOPTS *); static HRESULT (WINAPI *pEndBufferedPaint)(HPAINTBUFFER, BOOL); static HRESULT (WINAPI *pGetBufferedPaintBits)(HPAINTBUFFER, RGBQUAD **, int *); static HDC (WINAPI *pGetBufferedPaintDC)(HPAINTBUFFER); @@ -80,6 +81,7 @@ static void init_funcs(void) GET_PROC(uxtheme, BeginBufferedPaint) GET_PROC(uxtheme, BufferedPaintClear) GET_PROC(uxtheme, EndBufferedPaint) + GET_PROC(uxtheme, DrawThemeBackgroundEx) GET_PROC(uxtheme, GetBufferedPaintBits) GET_PROC(uxtheme, GetBufferedPaintDC) GET_PROC(uxtheme, GetBufferedPaintTargetDC) @@ -2261,6 +2263,15 @@ static void test_EnableThemeDialogTexture(void) UnregisterClassA(cls.lpszClassName, GetModuleHandleA(NULL)); }
+static void test_DrawThemeBackgroundEx(void) +{ + void *proc; + + proc = GetProcAddress(GetModuleHandleA("uxtheme.dll"), MAKEINTRESOURCEA(47)); + todo_wine + ok(proc == (void *)pDrawThemeBackgroundEx, "Expected DrawThemeBackgroundEx() at ordinal 47.\n"); +} + START_TEST(system) { ULONG_PTR ctx_cookie; @@ -2287,6 +2298,7 @@ START_TEST(system) test_GetThemeIntList(); test_GetThemeTransitionDuration(); test_DrawThemeParentBackground(); + test_DrawThemeBackgroundEx();
if (load_v6_module(&ctx_cookie, &ctx)) {
From: Zhiyi Zhang zzhang@codeweavers.com
Qt5 applications call DrawThemeBackgroundEx() by ordinal.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53066 Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/uxtheme/tests/system.c | 1 - dlls/uxtheme/uxtheme.spec | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index f169231b214..aa491ffb2d2 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -2268,7 +2268,6 @@ static void test_DrawThemeBackgroundEx(void) void *proc;
proc = GetProcAddress(GetModuleHandleA("uxtheme.dll"), MAKEINTRESOURCEA(47)); - todo_wine ok(proc == (void *)pDrawThemeBackgroundEx, "Expected DrawThemeBackgroundEx() at ordinal 47.\n"); }
diff --git a/dlls/uxtheme/uxtheme.spec b/dlls/uxtheme/uxtheme.spec index 140388245f2..c60254b677d 100644 --- a/dlls/uxtheme/uxtheme.spec +++ b/dlls/uxtheme/uxtheme.spec @@ -36,6 +36,7 @@ 44 stub -noname ClassicSystemParametersInfoA 45 stub -noname ClassicSystemParametersInfoW 46 stub -noname ClassicAdjustWindowRectEx +47 stdcall DrawThemeBackgroundEx(ptr ptr long long ptr ptr) 48 stub -noname GetThemeParseErrorInfo 60 stub -noname CreateThemeDataFromObjects 61 stdcall OpenThemeDataEx(ptr wstr long) @@ -53,7 +54,6 @@ @ stdcall BufferedPaintUnInit() @ stdcall CloseThemeData(ptr) @ stdcall DrawThemeBackground(ptr ptr long long ptr ptr) -@ stdcall DrawThemeBackgroundEx(ptr ptr long long ptr ptr) @ stdcall DrawThemeEdge(ptr ptr long long ptr long long ptr) @ stdcall DrawThemeIcon(ptr ptr long long ptr ptr long) @ stdcall DrawThemeParentBackground(ptr ptr ptr)
From: Zhiyi Zhang zzhang@codeweavers.com
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/uxtheme/tests/system.c | 133 ++++++++++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 4 deletions(-)
diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index aa491ffb2d2..e9191de1507 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -2265,10 +2265,139 @@ static void test_EnableThemeDialogTexture(void)
static void test_DrawThemeBackgroundEx(void) { + static const int width = 10, height = 10; + static const RECT rect = {0, 0, 10, 10}; + HBITMAP bitmap, old_bitmap; + BOOL transparent, found; + BITMAPINFO bitmap_info; + int i, glyph_type; + BYTE *bits, *ptr; + HTHEME htheme; void *proc; + HDC mem_dc; + HRESULT hr; + HWND hwnd;
proc = GetProcAddress(GetModuleHandleA("uxtheme.dll"), MAKEINTRESOURCEA(47)); ok(proc == (void *)pDrawThemeBackgroundEx, "Expected DrawThemeBackgroundEx() at ordinal 47.\n"); + + hwnd = CreateWindowA(WC_STATICA, "", WS_POPUP, 0, 0, 1, 1, 0, 0, 0, NULL); + ok(hwnd != NULL, "CreateWindowA failed, error %#lx.\n", GetLastError()); + htheme = OpenThemeData(hwnd, L"Spin"); + if (!htheme) + { + skip("Theming is inactive.\n"); + DestroyWindow(hwnd); + return; + } + + bitmap_info.bmiHeader.biSize = sizeof(bitmap_info.bmiHeader); + bitmap_info.bmiHeader.biWidth = width; + bitmap_info.bmiHeader.biHeight = height; + bitmap_info.bmiHeader.biPlanes = 1; + bitmap_info.bmiHeader.biBitCount = 32; + bitmap_info.bmiHeader.biCompression = BI_RGB; + bitmap = CreateDIBSection(0, &bitmap_info, DIB_RGB_COLORS, (void **)&bits, 0, 0); + mem_dc = CreateCompatibleDC(NULL); + old_bitmap = SelectObject(mem_dc, bitmap); + + /* Drawing opaque background with transparent glyphs should discard the alpha values from the glyphs */ + transparent = IsThemeBackgroundPartiallyTransparent(htheme, SPNP_UP, UPS_NORMAL); + ok(!transparent, "Expected spin button background opaque.\n"); + hr = GetThemeBool(htheme, SPNP_UP, UPS_NORMAL, TMT_TRANSPARENT, &transparent); + ok(hr == E_PROP_ID_UNSUPPORTED, "Got unexpected hr %#lx.\n", hr); + transparent = FALSE; + hr = GetThemeBool(htheme, SPNP_UP, UPS_NORMAL, TMT_GLYPHTRANSPARENT, &transparent); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(transparent, "Expected spin button glyph transparent.\n"); + + memset(bits, 0xa5, width * height * sizeof(int)); + hr = DrawThemeBackgroundEx(htheme, mem_dc, SPNP_UP, UPS_NORMAL, &rect, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ptr = bits; + for (i = 0; i < width * height; ++i) + { + if (ptr[3] != 0xff) + break; + + ptr += 4; + } + todo_wine + ok(i == width * height || broken(ptr[3] == 0) /* Spin button glyphs on XP don't use alpha */, + "Unexpected alpha value %#x at (%d,%d).\n", ptr[3], i % height, i / height); + + /* Drawing transparent background without glyphs should keep the alpha values */ + CloseThemeData(htheme); + htheme = OpenThemeData(hwnd, L"Scrollbar"); + transparent = IsThemeBackgroundPartiallyTransparent(htheme, SBP_SIZEBOX, SZB_RIGHTALIGN); + ok(transparent, "Expected scrollbar sizebox transparent.\n"); + transparent = FALSE; + hr = GetThemeBool(htheme, SBP_SIZEBOX, SZB_RIGHTALIGN, TMT_TRANSPARENT, &transparent); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(transparent, "Expected scrollbar sizebox transparent.\n"); + hr = GetThemeEnumValue(htheme, SBP_SIZEBOX, SZB_RIGHTALIGN, TMT_GLYPHTYPE, &glyph_type); + ok(hr == E_PROP_ID_UNSUPPORTED, "Got unexpected hr %#lx.\n", hr); + + memset(bits, 0xa5, width * height * sizeof(int)); + hr = DrawThemeBackgroundEx(htheme, mem_dc, SBP_SIZEBOX, SZB_RIGHTALIGN, &rect, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + found = FALSE; + ptr = bits; + for (i = 0; i < width * height; ++i) + { + if (ptr[3] == 0xa5) + { + found = TRUE; + break; + } + + ptr += 4; + } + ok(found, "Expected alpha values found.\n"); + + /* Drawing transparent background with transparent glyphs should keep alpha values */ + CloseThemeData(htheme); + htheme = OpenThemeData(hwnd, L"Header"); + if (IsThemePartDefined(htheme, HP_HEADERDROPDOWN, 0)) + { + transparent = IsThemeBackgroundPartiallyTransparent(htheme, HP_HEADERDROPDOWN, HDDS_NORMAL); + ok(transparent, "Expected header dropdown transparent.\n"); + transparent = FALSE; + hr = GetThemeBool(htheme, HP_HEADERDROPDOWN, HDDS_NORMAL, TMT_TRANSPARENT, &transparent); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(transparent, "Expected header dropdown background transparent.\n"); + transparent = FALSE; + hr = GetThemeBool(htheme, HP_HEADERDROPDOWN, HDDS_NORMAL, TMT_GLYPHTRANSPARENT, &transparent); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(transparent, "Expected header dropdown glyph transparent.\n"); + + memset(bits, 0xa5, width * height * sizeof(int)); + hr = DrawThemeBackgroundEx(htheme, mem_dc, HP_HEADERDROPDOWN, HDDS_NORMAL, &rect, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + found = FALSE; + ptr = bits; + for (i = 0; i < width * height; ++i) + { + if (ptr[3] == 0xa5) + { + found = TRUE; + break; + } + + ptr += 4; + } + ok(found, "Expected alpha values found.\n"); + } + else + { + skip("Failed to get header dropdown parts.\n"); + } + + SelectObject(mem_dc, old_bitmap); + DeleteDC(mem_dc); + DeleteObject(bitmap); + CloseThemeData(htheme); + DestroyWindow(hwnd); }
START_TEST(system) @@ -2279,10 +2408,6 @@ START_TEST(system) init_funcs(); init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
- /* No real functional theme API tests will be done (yet). The current tests - * only show input/return behaviour - */ - test_IsThemed(); test_IsThemePartDefined(); test_GetWindowTheme();
From: Zhiyi Zhang zzhang@codeweavers.com
Fix QSpinBox artifacts for Qt5 applications.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53066 Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/uxtheme/draw.c | 38 +++++++++++++++++++++++++++++++++++++ dlls/uxtheme/tests/system.c | 1 - 2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/dlls/uxtheme/draw.c b/dlls/uxtheme/draw.c index 3ddb9b3bf4d..2f5a161c988 100644 --- a/dlls/uxtheme/draw.c +++ b/dlls/uxtheme/draw.c @@ -523,6 +523,39 @@ static inline void get_transparency (HTHEME hTheme, int iPartId, int iStateId, } }
+/* Reset alpha values in hdc to 0xFF if the background is opaque */ +static void reset_dc_alpha_values(HTHEME htheme, HDC hdc, int part_id, int state_id, + const RECT *rect) +{ + static const RGBQUAD bitmap_bits = {0x0, 0x0, 0x0, 0xFF}; + BITMAPINFO bitmap_info = {0}; + RECT image_rect; + BOOL has_alpha; + HBITMAP hbmp; + int bg_type; + + if (GetDeviceCaps(hdc, BITSPIXEL) != 32) + return; + + if (FAILED(GetThemeEnumValue(htheme, part_id, state_id, TMT_BGTYPE, &bg_type)) + || bg_type != BT_IMAGEFILE) + return; + + if (FAILED(UXTHEME_LoadImage(htheme, part_id, state_id, rect, FALSE, &hbmp, &image_rect, + &has_alpha, NULL)) || has_alpha) + return; + + bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmap_info.bmiHeader.biWidth = 1; + bitmap_info.bmiHeader.biHeight = 1; + bitmap_info.bmiHeader.biPlanes = 1; + bitmap_info.bmiHeader.biBitCount = 32; + bitmap_info.bmiHeader.biCompression = BI_RGB; + StretchDIBits(hdc, rect->left, rect->top, abs(rect->right - rect->left), + abs(rect->bottom - rect->top), 0, 0, 1, 1, &bitmap_bits, &bitmap_info, + DIB_RGB_COLORS, SRCPAINT); +} + /*********************************************************************** * UXTHEME_DrawImageGlyph * @@ -581,6 +614,11 @@ static HRESULT UXTHEME_DrawImageGlyph(HTHEME hTheme, HDC hdc, int iPartId,
SelectObject(hdcSrc, oldSrc); DeleteDC(hdcSrc); + + /* Don't transfer alpha values from the glyph when drawing opaque background */ + if (SUCCEEDED(hr) && hasAlpha) + reset_dc_alpha_values(hTheme, hdc, iPartId, iStateId, pRect); + return hr; }
diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index e9191de1507..cbaf4b51258 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -2322,7 +2322,6 @@ static void test_DrawThemeBackgroundEx(void)
ptr += 4; } - todo_wine ok(i == width * height || broken(ptr[3] == 0) /* Spin button glyphs on XP don't use alpha */, "Unexpected alpha value %#x at (%d,%d).\n", ptr[3], i % height, i / height);
From: Zhiyi Zhang zzhang@codeweavers.com
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/uxtheme/tests/system.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index cbaf4b51258..e9c91c62638 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -2399,6 +2399,40 @@ static void test_DrawThemeBackgroundEx(void) DestroyWindow(hwnd); }
+static void test_GetThemeBackgroundRegion(void) +{ + HTHEME htheme; + HRGN region; + HRESULT hr; + HWND hwnd; + RECT rect; + int ret; + + hwnd = CreateWindowA(WC_STATICA, "", WS_POPUP, 0, 0, 1, 1, 0, 0, 0, NULL); + ok(hwnd != NULL, "CreateWindowA failed, error %#lx.\n", GetLastError()); + htheme = OpenThemeData(hwnd, L"Rebar"); + if (!htheme) + { + skip("Theming is inactive.\n"); + DestroyWindow(hwnd); + return; + } + + hr = GetThemeEnumValue(htheme, RP_BAND, 0, TMT_BGTYPE, &ret); + ok(hr == S_OK, "Got unexpected hr %#lx,\n", hr); + ok(ret == BT_NONE, "Got expected type %d.\n", ret); + + SetRect(&rect, 0, 0, 10, 10); + region = (HRGN)0xdeadbeef; + hr = GetThemeBackgroundRegion(htheme, NULL, RP_BAND, 0, &rect, ®ion); + todo_wine + ok(hr == E_UNEXPECTED || broken(hr == S_OK) /* < Win10 */, "Got unexpected hr %#lx.\n", hr); + ok(region == (HRGN)0xdeadbeef, "Got unexpected region.\n"); + + CloseThemeData(htheme); + DestroyWindow(hwnd); +} + START_TEST(system) { ULONG_PTR ctx_cookie; @@ -2422,6 +2456,7 @@ START_TEST(system) test_GetThemeTransitionDuration(); test_DrawThemeParentBackground(); test_DrawThemeBackgroundEx(); + test_GetThemeBackgroundRegion();
if (load_v6_module(&ctx_cookie, &ctx)) {
From: Zhiyi Zhang zzhang@codeweavers.com
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/uxtheme/draw.c | 6 +++++- dlls/uxtheme/tests/system.c | 1 - 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/uxtheme/draw.c b/dlls/uxtheme/draw.c index 2f5a161c988..0d5f05a9f6a 100644 --- a/dlls/uxtheme/draw.c +++ b/dlls/uxtheme/draw.c @@ -2063,8 +2063,12 @@ HRESULT WINAPI GetThemeBackgroundRegion(HTHEME hTheme, HDC hdc, int iPartId, if(!*pRegion) hr = HRESULT_FROM_WIN32(GetLastError()); } + else if (bgtype == BT_NONE) + { + hr = E_UNEXPECTED; + } else { - FIXME("Unknown background type\n"); + FIXME("Unknown background type %d\n", bgtype); /* This should never happen, and hence I don't know what to return */ hr = E_FAIL; } diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index e9c91c62638..aa566f554ff 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -2425,7 +2425,6 @@ static void test_GetThemeBackgroundRegion(void) SetRect(&rect, 0, 0, 10, 10); region = (HRGN)0xdeadbeef; hr = GetThemeBackgroundRegion(htheme, NULL, RP_BAND, 0, &rect, ®ion); - todo_wine ok(hr == E_UNEXPECTED || broken(hr == S_OK) /* < Win10 */, "Got unexpected hr %#lx.\n", hr); ok(region == (HRGN)0xdeadbeef, "Got unexpected region.\n");