From e307cad50176bca1c094db329029d0ebfe668de1 Mon Sep 17 00:00:00 2001 From: Whindmar Saksit Date: Sat, 21 Jun 2025 18:56:48 +0200 Subject: [PATCH] [UXTHEME] Implement SetSystemVisualStyle (#7864) Implement SetSystemVisualStyle based on function and flags found at https://stackoverflow.com/a/1036903 and https://pinvoke.net/default.aspx/uxtheme.SetSystemVisualStyle --- dll/cpl/desk/theme.c | 13 ++++++ dll/win32/uxtheme/system.c | 70 +++++++++++++++++++++++----- dll/win32/uxtheme/uxtheme.spec | 2 +- dll/win32/uxtheme/uxtheme_vista.spec | 2 +- sdk/include/reactos/uxundoc.h | 10 +++- 5 files changed, 82 insertions(+), 15 deletions(-) diff --git a/dll/cpl/desk/theme.c b/dll/cpl/desk/theme.c index cd457b180d5..a1b760f36dc 100644 --- a/dll/cpl/desk/theme.c +++ b/dll/cpl/desk/theme.c @@ -438,6 +438,19 @@ ApplyScheme(IN COLOR_SCHEME *scheme, IN PTHEME_SELECTION pSelectedTheme) StyleName, (lstrlenW(StyleName) + 1) * sizeof(WCHAR)); } + + if (pSelectedTheme->ThemeActive) + { + SHSetValueW(HKEY_CURRENT_USER, L"Control Panel\\Appearance", L"Current", REG_SZ, NULL, 0); + SHSetValueW(HKEY_CURRENT_USER, L"Control Panel\\Appearance", L"NewCurrent", REG_SZ, NULL, 0); + } + else if (pSelectedTheme->Color) + { + PCWSTR ClassicSchemeName = pSelectedTheme->Color->DisplayName; + DWORD cb = (lstrlenW(ClassicSchemeName) + 1) * sizeof(WCHAR); + SHSetValueW(HKEY_CURRENT_USER, L"Control Panel\\Appearance", L"Current", REG_SZ, ClassicSchemeName, cb); // 95+ + SHSetValueW(HKEY_CURRENT_USER, L"Control Panel\\Appearance", L"NewCurrent", REG_SZ, ClassicSchemeName, cb); // XP+ + } } static THEME* diff --git a/dll/win32/uxtheme/system.c b/dll/win32/uxtheme/system.c index 78a2940d6d2..3107a4e4662 100644 --- a/dll/win32/uxtheme/system.c +++ b/dll/win32/uxtheme/system.c @@ -545,12 +545,21 @@ static HRESULT UXTHEME_ApplyTheme(PTHEME_FILE tf) (lstrlenW(tf->pszSelectedSize)+1)*sizeof(WCHAR)); RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*)tf->szThemeFile, (lstrlenW(tf->szThemeFile)+1)*sizeof(WCHAR)); +#ifdef __REACTOS__ + { + WCHAR buf[sizeof("4294967295")]; + UINT cch = wsprintfW(buf, L"%u", GetUserDefaultUILanguage()); + RegSetValueExW(hKey, L"LastUserLangID", 0, REG_SZ, (const BYTE*)buf, ++cch * sizeof(WCHAR)); + } +#endif } else { RegDeleteValueW(hKey, szColorName); RegDeleteValueW(hKey, szSizeName); RegDeleteValueW(hKey, szDllName); - +#ifdef __REACTOS__ + RegDeleteValueW(hKey, L"LastUserLangID"); +#endif } RegCloseKey(hKey); } @@ -1215,32 +1224,62 @@ HRESULT WINAPI CloseThemeFile(HTHEMEFILE hThemeFile) * * PARAMS * hThemeFile Handle to theme file - * unknown See notes + * Flags Unknown flag bits * hWnd Window requesting the theme change * * RETURNS * Success: S_OK * Failure: HRESULT error-code - * - * NOTES - * I'm not sure what the second parameter is (the datatype is likely wrong), other then this: - * Under XP if I pass - * char b[] = ""; - * the theme is applied with the screen redrawing really badly (flickers) - * char b[] = "\0"; where \0 can be one or more of any character, makes no difference - * the theme is applied smoothly (screen does not flicker) - * char *b = "\0" or NULL; where \0 can be zero or more of any character, makes no difference - * the function fails returning invalid parameter... very strange */ +#ifdef __REACTOS__ +HRESULT WINAPI ApplyTheme(HTHEMEFILE hThemeFile, UINT Flags, HWND hWnd) +#else HRESULT WINAPI ApplyTheme(HTHEMEFILE hThemeFile, char *unknown, HWND hWnd) +#endif { HRESULT hr; +#ifdef __REACTOS__ + TRACE("(%p,%#x,%p)\n", hThemeFile, Flags, hWnd); +#else TRACE("(%p,%s,%p)\n", hThemeFile, unknown, hWnd); +#endif hr = UXTHEME_ApplyTheme(hThemeFile); UXTHEME_broadcast_theme_changed (NULL, (g_ActiveThemeFile != NULL)); return hr; } +#ifdef __REACTOS__ +/********************************************************************** + * SetSystemVisualStyle (UXTHEME.65) + */ +HRESULT WINAPI SetSystemVisualStyle(PCWSTR pszStyleFile, PCWSTR pszColor, PCWSTR pszSize, UINT Flags) +{ + PTHEME_FILE pThemeFile = NULL; + HRESULT hr; + + if (pszStyleFile) + { + if (!g_bThemeHooksActive) + return E_FAIL; + + if (pszColor && !*pszColor) + pszColor = NULL; + if (pszSize && !*pszSize) + pszSize = NULL; + + hr = MSSTYLES_OpenThemeFile(pszStyleFile, pszColor, pszSize, &pThemeFile); + if (FAILED(hr)) + return hr; + } + hr = ApplyTheme(pThemeFile, Flags, NULL); + + if (pThemeFile) + MSSTYLES_CloseThemeFile(pThemeFile); + + return hr; +} +#endif // __REACTOS__ + /********************************************************************** * GetThemeDefaults (UXTHEME.7) * @@ -1273,8 +1312,15 @@ HRESULT WINAPI GetThemeDefaults(LPCWSTR pszThemeFileName, LPWSTR pszColorName, hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, NULL, &pt); if(FAILED(hr)) return hr; +#ifdef __REACTOS__ + if (pszColorName) + lstrcpynW(pszColorName, pt->pszSelectedColor, dwColorNameLen); + if (pszSizeName) + lstrcpynW(pszSizeName, pt->pszSelectedSize, dwSizeNameLen); +#else lstrcpynW(pszColorName, pt->pszSelectedColor, dwColorNameLen); lstrcpynW(pszSizeName, pt->pszSelectedSize, dwSizeNameLen); +#endif MSSTYLES_CloseThemeFile(pt); return S_OK; diff --git a/dll/win32/uxtheme/uxtheme.spec b/dll/win32/uxtheme/uxtheme.spec index 17d90eef273..8ad872a79b0 100644 --- a/dll/win32/uxtheme/uxtheme.spec +++ b/dll/win32/uxtheme/uxtheme.spec @@ -62,7 +62,7 @@ 62 stub -noname ServerClearStockObjects 63 stub -noname MarkSelection #64 ProcessLoadTheme_RunDLLW -#65 SetSystemVisualStyle +65 stdcall -noname SetSystemVisualStyle(wstr wstr wstr long) #66 ServiceClearStockObjects 67 stdcall GetThemeIntList(ptr long long long ptr) 68 stdcall GetThemeMargins(ptr ptr long long long ptr ptr) diff --git a/dll/win32/uxtheme/uxtheme_vista.spec b/dll/win32/uxtheme/uxtheme_vista.spec index bc9992900c2..03172f50090 100644 --- a/dll/win32/uxtheme/uxtheme_vista.spec +++ b/dll/win32/uxtheme/uxtheme_vista.spec @@ -62,7 +62,7 @@ 62 stub -noname ServerClearStockObjects 63 stub -noname MarkSelection 64 stub ProcessLoadTheme_RunDLLW -65 stub SetSystemVisualStyle +65 stdcall -noname SetSystemVisualStyle(wstr wstr wstr long) 66 stub ServiceClearStockObjects 67 stdcall -stub AddThemeAppCompatFlag(ptr long long long ptr) 68 stdcall -stub ResetThemeAppCompatFlags(ptr ptr long long long ptr ptr) diff --git a/sdk/include/reactos/uxundoc.h b/sdk/include/reactos/uxundoc.h index 2c6e23cb22b..71f0fe709e7 100644 --- a/sdk/include/reactos/uxundoc.h +++ b/sdk/include/reactos/uxundoc.h @@ -81,10 +81,18 @@ HRESULT WINAPI OpenThemeFile(LPCWSTR pszThemeFileName, HRESULT WINAPI CloseThemeFile(HTHEMEFILE hThemeFile); +#define UXTAPPLYFLAG_LOADSYSTEMMETRICS 0x01 // https://stackoverflow.com/a/1036903 +#define UXTAPPLYFLAG_APPLYSYSTEMMETRICS 0x20 // https://stackoverflow.com/a/1036903 + HRESULT WINAPI ApplyTheme(HTHEMEFILE hThemeFile, - char *unknown, + UINT Flags, HWND hWnd); +HRESULT WINAPI SetSystemVisualStyle(PCWSTR pszStyleFile, + PCWSTR pszColor, + PCWSTR pszSize, + UINT Flags); + HRESULT WINAPI GetThemeDefaults(LPCWSTR pszThemeFileName, LPWSTR pszColorName, DWORD dwColorNameLen,