[Bug 51348] New: uxtheme.SetWindowTheme should use SendMessage to send WM_THEMECHANGED

WineHQ Bugzilla wine-bugs at winehq.org
Sun Jun 27 09:15:12 CDT 2021


https://bugs.winehq.org/show_bug.cgi?id=51348

            Bug ID: 51348
           Summary: uxtheme.SetWindowTheme should use SendMessage to send
                    WM_THEMECHANGED
           Product: Wine
           Version: 6.11
          Hardware: x86-64
                OS: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: uxtheme
          Assignee: wine-bugs at winehq.org
          Reporter: x1917x at gmail.com
      Distribution: ---

Created attachment 70205
  --> https://bugs.winehq.org/attachment.cgi?id=70205
Bad behavior

The issue affects SourceInsight 4 in particular. SourceInsight has its own
built-in theme functionality which doesn't get along well with any non-standard
Wine theme.

When a non-standard Wine theme is selected, then the main toolbar in SI4
ignores its app theme and always gets drawn with the selected Wine theme.
Selecting the default Wine theme fixes the issue - the toolbar is drawn
according to the app theme. On Windows it's ok no matter which UI theme is set.
Screenshot of the issue is attached.

The root cause of the issue is that
UXTHEME_broadcast_msg/UXTHEME_broadcast_msg_enumchild in dlls/uxtheme/system.c
both use a PostMessage() call to send WM_THEMECHANGED to affected window(s).

In SI4 the main toolbar is implemented as a combination of a custom container
window (si_Rebar class) and a standard win32 Rebar control (RebarWindow32
class).

Immediately after creating the RebarWindow32 window, SI4 does
SetWindowTheme(hwndRebar, L" ", L" ") for it.

According to MSDN
(https://docs.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-setwindowtheme)

> The theme manager retains the pszSubAppName and the pszSubIdList associations through the lifetime of the window, even if visual styles subsequently change. The window is sent a WM_THEMECHANGED message at the end of a SetWindowTheme call, so that the new visual style can be found and applied.
>
> When pszSubAppName and pszSubIdList are NULL, the theme manager removes the previously applied associations. You can prevent visual styles from being applied to a specified window by specifying an empty string, (L" "), which does not match any section entries.

- this L" ", L" " stuff means that SI4 DOES NOT want for system visual styles
being applied to its RebarWindow32 control. However, according to WINEDEBUG
logs they were applied to all bg erase, painting etc operations no matter the
SetWindowTheme(, L" ", L" ") call.

Turns out that RebarWindow32' WndProc receives WM_THEMECHANGED too late, after
all stuff including drawing already happened with the system-wide theme being
applied. The reason why it was received so late is simple - SetWindowTheme
implementation in wine uses PostMessage() instead of SendMessage(). Replacing
it with a SendMessage() call allows to fix the bug.

I've checked what Windows actually does in SetWindowTheme and found out that it
always uses SendMessage to send WM_THEMECHANGED (for any HWND).


So. suggested fix:

diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c
index a37e532500a..3b6e6d2b6b6 100644
--- a/dlls/uxtheme/system.c
+++ b/dlls/uxtheme/system.c
@@ -59,7 +59,7 @@ static WCHAR szCurrentSize[64];

 static BOOL CALLBACK UXTHEME_broadcast_msg_enumchild (HWND hWnd, LPARAM msg)
 {
-    PostMessageW(hWnd, msg, 0, 0);
+    SendMessageW(hWnd, msg, 0, 0);
     return TRUE;
 }

@@ -72,7 +72,7 @@ static BOOL CALLBACK UXTHEME_broadcast_msg (HWND hWnd, LPARAM
msg)
     }
     else
     {
-    PostMessageW(hWnd, msg, 0, 0);
+    SendMessageW(hWnd, msg, 0, 0);
     EnumChildWindows (hWnd, UXTHEME_broadcast_msg_enumchild, msg);
     }
     return TRUE;

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list