[PATCH 6/9] comctl32/propsheet: Handle WM_CTLCOLORSTATIC in the property sheet page window procedure.

Zhiyi Zhang zzhang at codeweavers.com
Tue Dec 7 03:13:03 CST 2021


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 at codeweavers.com>
---
 dlls/comctl32/propsheet.c       | 42 +++++++++++++++++++++++++++++++++
 dlls/comctl32/tests/propsheet.c | 12 +++-------
 dlls/comctl32/tests/static.c    |  5 ----
 dlls/uxtheme/dialog.c           | 28 ----------------------
 4 files changed, 45 insertions(+), 42 deletions(-)

diff --git a/dlls/comctl32/propsheet.c b/dlls/comctl32/propsheet.c
index 556d63f2c75..4fe80241855 100644
--- a/dlls/comctl32/propsheet.c
+++ b/dlls/comctl32/propsheet.c
@@ -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);
diff --git a/dlls/comctl32/tests/propsheet.c b/dlls/comctl32/tests/propsheet.c
index eaaa00efe97..199b280879e 100644
--- a/dlls/comctl32/tests/propsheet.c
+++ b/dlls/comctl32/tests/propsheet.c
@@ -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);
diff --git a/dlls/comctl32/tests/static.c b/dlls/comctl32/tests/static.c
index ce21e03df3c..b507cf1e02b 100644
--- a/dlls/comctl32/tests/static.c
+++ b/dlls/comctl32/tests/static.c
@@ -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
 }
diff --git a/dlls/uxtheme/dialog.c b/dlls/uxtheme/dialog.c
index d0055e013a0..bbfdaba639b 100644
--- a/dlls/uxtheme/dialog.c
+++ b/dlls/uxtheme/dialog.c
@@ -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);
-- 
2.32.0




More information about the wine-devel mailing list