Load, validate and retrieve a few properties from an msstyles theme.
diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c
index 0d82ec6..ba9f6be 100644
--- a/dlls/uxtheme/system.c
+++ b/dlls/uxtheme/system.c
@@ -26,9 +26,12 @@
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
+#include "winreg.h"
+#include "shlwapi.h"
#include "uxtheme.h"
#include "uxthemedll.h"
+#include "msstyles.h"
#include "wine/debug.h"
@@ -38,11 +41,28 @@
* Defines and global variables
*/
+static const WCHAR szThemeManager[] = {
+ 'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\',
+ 'W','i','n','d','o','w','s','\\',
+ 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+ 'T','h','e','m','e','M','a','n','a','g','e','r','\0'
+};
+static const WCHAR szThemeActive[] = {'T','h','e','m','e','A','c','t','i','v','e','\0'};
+static const WCHAR szSizeName[] = {'S','i','z','e','N','a','m','e','\0'};
+static const WCHAR szColorName[] = {'C','o','l','o','r','N','a','m','e','\0'};
+static const WCHAR szDllName[] = {'D','l','l','N','a','m','e','\0'};
+
DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS;
ATOM atWindowTheme;
ATOM atSubAppName;
ATOM atSubIdList;
+BOOL bThemeActive = FALSE;
+WCHAR szCurrentTheme[MAX_PATH];
+WCHAR szCurrentColor[64];
+WCHAR szCurrentSize[64];
+
/***********************************************************************/
/***********************************************************************
@@ -59,10 +79,65 @@
const WCHAR szSubIdList[] = {
'u','x','_','s','u','b','i','d','l','s','t','\0'
};
+ HKEY hKey;
+ LONG buffsize;
+ HRESULT hr;
+ WCHAR tmp[10];
+ PTHEME_FILE pt;
atWindowTheme = GlobalAddAtomW(szWindowTheme);
atSubAppName = GlobalAddAtomW(szSubAppName);
atSubIdList = GlobalAddAtomW(szSubIdList);
+
+ /* Get current theme configuration */
+ if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
+ TRACE("Loading theme config\n");
+ buffsize = sizeof(tmp)/sizeof(tmp[0]);
+ if(!RegQueryValueExW(hKey, szThemeActive, NULL, NULL, (LPBYTE)tmp, &buffsize)) {
+ bThemeActive = (tmp[0] != '0');
+ }
+ else {
+ bThemeActive = FALSE;
+ TRACE("Failed to get ThemeActive: %ld\n", GetLastError());
+ }
+ buffsize = sizeof(szCurrentColor)/sizeof(szCurrentColor[0]);
+ if(RegQueryValueExW(hKey, szColorName, NULL, NULL, (LPBYTE)szCurrentColor, &buffsize))
+ szCurrentColor[0] = '\0';
+ buffsize = sizeof(szCurrentSize)/sizeof(szCurrentSize[0]);
+ if(RegQueryValueExW(hKey, szSizeName, NULL, NULL, (LPBYTE)szCurrentSize, &buffsize))
+ szCurrentSize[0] = '\0';
+ if(SHRegGetPathW(hKey, NULL, szDllName, szCurrentTheme, 0))
+ szCurrentTheme[0] = '\0';
+ RegCloseKey(hKey);
+ }
+ else
+ TRACE("Failed to open theme registry key\n");
+
+ if(bThemeActive) {
+ /* Make sure the theme requested is actually valid */
+ hr = MSSTYLES_OpenThemeFile(szCurrentTheme,
+ szCurrentColor[0]?szCurrentColor:NULL,
+ szCurrentSize[0]?szCurrentSize:NULL,
+ &pt);
+ if(FAILED(hr)) {
+ bThemeActive = FALSE;
+ szCurrentTheme[0] = '\0';
+ szCurrentColor[0] = '\0';
+ szCurrentSize[0] = '\0';
+ }
+ else {
+ /* Make sure the global color & size match the theme */
+ lstrcpynW(szCurrentColor, pt->pszSelectedColor, sizeof(szCurrentColor)/sizeof(szCurrentColor[0]));
+ lstrcpynW(szCurrentSize, pt->pszSelectedSize, sizeof(szCurrentSize)/sizeof(szCurrentSize[0]));
+ MSSTYLES_CloseThemeFile(pt);
+ }
+ }
+
+ if(!bThemeActive)
+ TRACE("Themeing not active\n");
+ else
+ TRACE("Theme active: %s %s %s\n", debugstr_w(szCurrentTheme),
+ debugstr_w(szCurrentColor), debugstr_w(szCurrentSize));
}
/***********************************************************************
@@ -70,8 +145,7 @@
*/
BOOL WINAPI IsAppThemed(void)
{
- FIXME("stub\n");
- return FALSE;
+ return IsThemeActive();
}
/***********************************************************************
@@ -79,8 +153,8 @@
*/
BOOL WINAPI IsThemeActive(void)
{
- FIXME("stub\n");
- return FALSE;
+ TRACE("\n");
+ return bThemeActive;
}
/***********************************************************************
@@ -91,8 +165,21 @@
*/
HRESULT WINAPI EnableTheming(BOOL fEnable)
{
- FIXME("%d: stub\n", fEnable);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ HKEY hKey;
+ WCHAR szEnabled[] = {'0','\0'};
+
+ TRACE("(%d)\n", fEnable);
+
+ if(fEnable != bThemeActive) {
+ bThemeActive = fEnable;
+ if(bThemeActive) szEnabled[0] = '1';
+ if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
+ RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (LPBYTE)szEnabled, sizeof(WCHAR));
+ RegCloseKey(hKey);
+ }
+ PostMessageW(HWND_BROADCAST, WM_THEMECHANGED, 0, 0);
+ }
+ return S_OK;
}
/***********************************************************************
@@ -151,7 +238,9 @@
debugstr_w(pszSubIdList));
hr = UXTHEME_SetWindowProperty(hwnd, atSubAppName, pszSubAppName);
if(SUCCEEDED(hr))
- hr = UXTHEME_SetWindowProperty(hwnd, atSubIdList, pszSubIdList);
+ hr = UXTHEME_SetWindowProperty(hwnd, atSubIdList, pszSubIdList);
+ if(SUCCEEDED(hr))
+ PostMessageW(hwnd, WM_THEMECHANGED, 0, 0);
return hr;
}
@@ -162,8 +251,12 @@
LPWSTR pszColorBuff, int cchMaxColorChars,
LPWSTR pszSizeBuff, int cchMaxSizeChars)
{
- FIXME("stub\n");
- return ERROR_CALL_NOT_IMPLEMENTED;
+ if(!bThemeActive)
+ return E_PROP_ID_UNSUPPORTED;
+ if(pszThemeFileName) lstrcpynW(pszThemeFileName, szCurrentTheme, dwMaxNameChars);
+ if(pszColorBuff) lstrcpynW(pszColorBuff, szCurrentColor, cchMaxColorChars);
+ if(pszSizeBuff) lstrcpynW(pszSizeBuff, szCurrentSize, cchMaxSizeChars);
+ return S_OK;
}
/***********************************************************************
@@ -249,10 +342,10 @@
LPCWSTR pszSizeName, HTHEMEFILE *hThemeFile,
DWORD unknown)
{
- FIXME("%s,%s,%s,%ld: stub\n", debugstr_w(pszThemeFileName),
- debugstr_w(pszColorName),
- debugstr_w(pszSizeName), unknown);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ TRACE("(%s,%s,%s,%p,%ld)\n", debugstr_w(pszThemeFileName),
+ debugstr_w(pszColorName), debugstr_w(pszSizeName),
+ hThemeFile, unknown);
+ return MSSTYLES_OpenThemeFile(pszThemeFileName, pszColorName, pszSizeName, (PTHEME_FILE*)hThemeFile);
}
/**********************************************************************
@@ -265,7 +358,8 @@
*/
HRESULT WINAPI CloseThemeFile(HTHEMEFILE hThemeFile)
{
- FIXME("stub\n");
+ TRACE("(%p)\n", hThemeFile);
+ MSSTYLES_CloseThemeFile(hThemeFile);
return S_OK;
}
@@ -311,8 +405,20 @@
DWORD dwColorNameLen, LPWSTR pszSizeName,
DWORD dwSizeNameLen)
{
- FIXME("%s: stub\n", debugstr_w(pszThemeFileName));
- return ERROR_CALL_NOT_IMPLEMENTED;
+ PTHEME_FILE pt;
+ HRESULT hr;
+ TRACE("(%s,%p,%ld,%p,%ld)\n", debugstr_w(pszThemeFileName),
+ pszColorName, dwColorNameLen,
+ pszSizeName, dwSizeNameLen);
+
+ hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, NULL, &pt);
+ if(FAILED(hr)) return hr;
+
+ lstrcpynW(pszColorName, pt->pszSelectedColor, dwColorNameLen);
+ lstrcpynW(pszSizeName, pt->pszSelectedSize, dwSizeNameLen);
+
+ MSSTYLES_CloseThemeFile(pt);
+ return S_OK;
}
/**********************************************************************
@@ -354,13 +460,37 @@
* NOTES
* XP fails with E_POINTER when pszColorName points to a buffer smaller then 605
* characters
+ *
+ * Not very efficient that I'm opening & validating the theme every call, but
+ * this is undocumented and almost never called..
+ * (and this is how windows works too)
*/
HRESULT WINAPI EnumThemeColors(LPWSTR pszThemeFileName, LPWSTR pszSizeName,
DWORD dwColorNum, LPWSTR pszColorName)
{
- FIXME("%s %s %ld: stub\n", debugstr_w(pszThemeFileName),
+ PTHEME_FILE pt;
+ HRESULT hr;
+ LPWSTR tmp;
+ TRACE("(%s,%s,%ld)\n", debugstr_w(pszThemeFileName),
debugstr_w(pszSizeName), dwColorNum);
- return ERROR_CALL_NOT_IMPLEMENTED;
+
+ hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, pszSizeName, &pt);
+ if(FAILED(hr)) return hr;
+
+ tmp = pt->pszAvailColors;
+ while(dwColorNum && *tmp) {
+ dwColorNum--;
+ tmp += lstrlenW(tmp)+1;
+ }
+ if(!dwColorNum && *tmp) {
+ TRACE("%s\n", debugstr_w(tmp));
+ lstrcpyW(pszColorName, tmp);
+ }
+ else
+ hr = E_PROP_ID_UNSUPPORTED;
+
+ MSSTYLES_CloseThemeFile(pt);
+ return hr;
}
/**********************************************************************
@@ -383,12 +513,37 @@
* NOTES
* XP fails with E_POINTER when pszSizeName points to a buffer smaller then 605
* characters
+ *
+ * Not very efficient that I'm opening & validating the theme every call, but
+ * this is undocumented and almost never called..
+ * (and this is how windows works too)
*/
HRESULT WINAPI EnumThemeSizes(LPWSTR pszThemeFileName, LPWSTR pszColorName,
DWORD dwSizeNum, LPWSTR pszSizeName)
{
- FIXME("%s %s %ld: stub\n", debugstr_w(pszThemeFileName), debugstr_w(pszColorName), dwSizeNum);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ PTHEME_FILE pt;
+ HRESULT hr;
+ LPWSTR tmp;
+ TRACE("(%s,%s,%ld)\n", debugstr_w(pszThemeFileName),
+ debugstr_w(pszColorName), dwSizeNum);
+
+ hr = MSSTYLES_OpenThemeFile(pszThemeFileName, pszColorName, NULL, &pt);
+ if(FAILED(hr)) return hr;
+
+ tmp = pt->pszAvailSizes;
+ while(dwSizeNum && *tmp) {
+ dwSizeNum--;
+ tmp += lstrlenW(tmp)+1;
+ }
+ if(!dwSizeNum && *tmp) {
+ TRACE("%s\n", debugstr_w(tmp));
+ lstrcpyW(pszSizeName, tmp);
+ }
+ else
+ hr = E_PROP_ID_UNSUPPORTED;
+
+ MSSTYLES_CloseThemeFile(pt);
+ return hr;
}
/**********************************************************************