comctl32/propsheet: Handle WM_CTLCOLORSTATIC in the property sheet page window procedure.

Move themed WM_CTLCOLORSTATIC handling from UXTHEME_DefDlgProc() to the property sheet page window
procedure.

Fix a regression from 2f1bbd8 that makes the static controls in file open dialog to have black
background when using some themes.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51987
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2021-12-07 17:13:03 +08:00 committed by Alexandre Julliard
parent ee1b19aa16
commit b1ccad4b5c
4 changed files with 45 additions and 42 deletions

View file

@ -1196,6 +1196,36 @@ PROPSHEET_WizardSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
/* Subclassing window procedure for theming dialogs in property sheet pages */
static LRESULT CALLBACK PROPSHEET_ThemedSubclassProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
UINT_PTR id, DWORD_PTR ref)
{
WNDPROC dlgproc;
LRESULT lr;
HDC hdc;
switch (msg)
{
case WM_CTLCOLORSTATIC:
{
if (!IsThemeActive() || !IsThemeDialogTextureEnabled(hwnd))
break;
dlgproc = (WNDPROC)GetWindowLongPtrW(hwnd, DWLP_DLGPROC);
lr = CallWindowProcW(dlgproc, hwnd, msg, wp, lp);
if (lr)
return lr;
hdc = (HDC)wp;
SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
SetBkMode(hdc, TRANSPARENT);
return (LRESULT)GetStockObject(NULL_BRUSH);
}
}
return DefSubclassProc(hwnd, msg, wp, lp);
}
/*
* Get the size of an in-memory Template
*
@ -1467,6 +1497,10 @@ static BOOL PROPSHEET_CreatePage(HWND hwndParent,
SetWindowSubclass(hwndPage, PROPSHEET_WizardSubclassProc, 1,
(DWORD_PTR)ppshpage);
}
else
{
SetWindowSubclass(hwndPage, PROPSHEET_ThemedSubclassProc, 1, (DWORD_PTR)ppshpage);
}
if (!(psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD))
EnableThemeDialogTexture (hwndPage, ETDT_ENABLETAB);
@ -2408,6 +2442,10 @@ static BOOL PROPSHEET_RemovePage(HWND hwndDlg,
RemoveWindowSubclass(psInfo->proppage[index].hwndPage,
PROPSHEET_WizardSubclassProc, 1);
}
else
{
RemoveWindowSubclass(psInfo->proppage[index].hwndPage, PROPSHEET_ThemedSubclassProc, 1);
}
/* Destroy page dialog window */
DestroyWindow(psInfo->proppage[index].hwndPage);
@ -2725,6 +2763,10 @@ static void PROPSHEET_CleanUp(HWND hwndDlg)
RemoveWindowSubclass(psInfo->proppage[i].hwndPage,
PROPSHEET_WizardSubclassProc, 1);
}
else
{
RemoveWindowSubclass(psInfo->proppage[i].hwndPage, PROPSHEET_ThemedSubclassProc, 1);
}
if(psInfo->proppage[i].hwndPage)
DestroyWindow(psInfo->proppage[i].hwndPage);

View file

@ -1298,13 +1298,11 @@ static void test_WM_CTLCOLORSTATIC(void)
/* Test that device context is set to transparent after WM_CTLCOLORSTATIC */
mode = SetBkMode(child_hdc, old_mode);
todo_wine_if(pGetWindowTheme(sheethwnd) == NULL)
ok(mode == TRANSPARENT, "Expected mode %#x, got %#x.\n", TRANSPARENT, mode);
/* Test that the brush is a pattern brush created from the tab body bitmap in the theme */
todo_wine_if(pGetWindowTheme(sheethwnd) == NULL)
ok(hbrush != GetSysColorBrush(COLOR_BTNFACE), "Expected a different brush.\n");
todo_wine_if(pGetWindowTheme(sheethwnd) != NULL)
todo_wine_if(is_theme_active)
ok(hbrush != GetStockObject(NULL_BRUSH), "Expected a different brush.\n");
hbrush2 = SelectObject(child_hdc, GetSysColorBrush(COLOR_BTNFACE));
ok(hbrush2 != hbrush, "Expected a different brush.\n");
@ -1312,7 +1310,6 @@ static void test_WM_CTLCOLORSTATIC(void)
memset(&log_brush, 0, sizeof(log_brush));
count = GetObjectA(hbrush, sizeof(log_brush), &log_brush);
ok(count == sizeof(log_brush), "GetObjectA failed, error %u.\n", GetLastError());
todo_wine_if(pGetWindowTheme(sheethwnd) == NULL)
ok(log_brush.lbColor == 0, "Expected brush color %#x, got %#x.\n", 0, log_brush.lbColor);
todo_wine
ok(log_brush.lbStyle == BS_PATTERN, "Expected brush style %#x, got %#x.\n", BS_PATTERN,
@ -1360,10 +1357,8 @@ static void test_WM_CTLCOLORSTATIC(void)
old_mode = SetBkMode(hdc, OPAQUE);
ok(old_mode != 0, "SetBkMode failed.\n");
hbrush2 = (HBRUSH)SendMessageW(sheethwnd, WM_CTLCOLORSTATIC, (WPARAM)hdc, (LPARAM)hwnd);
todo_wine_if(pGetWindowTheme(sheethwnd) != NULL)
ok(hbrush2 == hbrush, "Expected the same brush.\n");
mode = SetBkMode(hdc, old_mode);
todo_wine
ok(mode == TRANSPARENT, "Expected mode %#x, got %#x.\n", TRANSPARENT, mode);
ReleaseDC(hwnd, hdc);
DestroyWindow(hwnd);
@ -1374,7 +1369,6 @@ static void test_WM_CTLCOLORSTATIC(void)
hr = pEnableThemeDialogTexture(sheethwnd, ETDT_DISABLE);
ok(hr == S_OK, "EnableThemeDialogTexture failed, hr %#x.\n", hr);
hbrush2 = (HBRUSH)SendMessageW(sheethwnd, WM_CTLCOLORSTATIC, (WPARAM)child_hdc, (LPARAM)child);
todo_wine_if(pGetWindowTheme(sheethwnd) == NULL)
ok(hbrush2 != hbrush, "Expected a different brush.\n");
ok(hbrush2 == GetSysColorBrush(COLOR_BTNFACE), "Expected brush %p, got %p.\n",
GetSysColorBrush(COLOR_BTNFACE), hbrush2);
@ -1456,11 +1450,11 @@ static void test_WM_CTLCOLORSTATIC(void)
ok(ret, "GetBrushOrgEx failed, error %u.\n", GetLastError());
ok(org.x == 0 && org.y == 0, "Expected (0,0), got %s.\n", wine_dbgstr_point(&org));
todo_wine_if(pGetWindowTheme(sheethwnd) != NULL)
todo_wine_if(is_theme_active)
ok(hbrush == GetSysColorBrush(COLOR_BTNFACE), "Expected brush %p, got %p.\n",
GetSysColorBrush(COLOR_BTNFACE), hbrush);
mode = SetBkMode(child_hdc, old_mode);
todo_wine_if(pGetWindowTheme(sheethwnd) != NULL)
todo_wine_if(is_theme_active)
ok(mode == OPAQUE, "Expected mode %#x, got %#x.\n", OPAQUE, mode);
}
color = SetBkColor(child_hdc, old_color);

View file

@ -42,7 +42,6 @@ static int g_nReceivedColorStatic;
static HRESULT (WINAPI *pEnableThemeDialogTexture)(HWND, DWORD);
static HTHEME (WINAPI *pGetWindowTheme)(HWND);
static BOOL (WINAPI *pIsThemeActive)(void);
static BOOL (WINAPI *pIsThemeDialogTextureEnabled)(HWND);
/* try to make sure pending X events have been processed before continuing */
@ -452,14 +451,12 @@ static void test_WM_CTLCOLORSTATIC(void)
ok(pGetWindowTheme(dialog) == NULL, "Expected NULL theme handle.\n");
brush = (HBRUSH)SendMessageW(dialog, WM_CTLCOLORSTATIC, (WPARAM)child_hdc, (LPARAM)child);
todo_wine_if(todo)
ok(brush == GetSysColorBrush(COLOR_BTNFACE), "Expected brush %p, got %p.\n",
GetSysColorBrush(COLOR_BTNFACE), brush);
color = SetBkColor(child_hdc, old_color);
ok(color == GetSysColor(COLOR_BTNFACE), "Expected background color %#x, got %#x.\n",
GetSysColor(COLOR_BTNFACE), color);
mode = SetBkMode(child_hdc, old_mode);
todo_wine_if(todo)
ok(mode == OPAQUE, "Expected mode %#x, got %#x.\n", OPAQUE, mode);
color = GetPixel(dialog_hdc, 40, 40);
ok(color == 0, "Expected pixel %#x, got %#x.\n", 0, color);
@ -475,7 +472,6 @@ static void test_WM_CTLCOLORSTATIC(void)
ok(ret, "Expected theme dialog texture enabled.\n");
brush = (HBRUSH)SendMessageW(dialog, WM_CTLCOLORSTATIC, (WPARAM)child_hdc, (LPARAM)child);
todo_wine_if(pIsThemeActive())
ok(brush == GetSysColorBrush(COLOR_BTNFACE), "Expected brush %p, got %p.\n",
GetSysColorBrush(COLOR_BTNFACE), brush);
@ -497,7 +493,6 @@ static void init_functions(void)
#define X(f) p##f = (void *)GetProcAddress(uxtheme, #f);
X(EnableThemeDialogTexture)
X(GetWindowTheme)
X(IsThemeActive)
X(IsThemeDialogTextureEnabled)
#undef X
}

View file

@ -89,34 +89,6 @@ LRESULT WINAPI UXTHEME_DefDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
return 1;
}
case WM_CTLCOLORSTATIC:
if (!doTheming) return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
{
WNDPROC dlgp = (WNDPROC)GetWindowLongPtrW (hWnd, DWLP_DLGPROC);
LRESULT result = CallWindowProcW(dlgp, hWnd, msg, wParam, lParam);
if (!result)
{
/* Override defaults with more suitable values when themed */
HDC controlDC = (HDC)wParam;
HWND controlWnd = (HWND)lParam;
WCHAR controlClass[32];
GetClassNameW (controlWnd, controlClass, ARRAY_SIZE(controlClass));
if (lstrcmpiW (controlClass, WC_STATICW) == 0)
{
SetBkColor(controlDC, GetSysColor(COLOR_BTNFACE));
SetBkMode (controlDC, TRANSPARENT);
/* Return NULL brush since we painted the BG already */
return (LRESULT)GetStockObject (NULL_BRUSH);
}
else
return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
}
return result;
}
default:
/* Call old proc */
return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);