*/
#include "uxthemep.h"
-#include <wine/debug.h>
-WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
+#include <stdio.h>
+#include <winreg.h>
+#include <uxundoc.h>
/***********************************************************************
* Defines and global variables
ATOM atWindowTheme;
static ATOM atSubAppName;
static ATOM atSubIdList;
-ATOM atWndContrext;
+ATOM atWndContext;
-static BOOL bThemeActive = FALSE;
-
-static PTHEME_FILE ActiveThemeFile;
+PTHEME_FILE ActiveThemeFile;
/***********************************************************************/
static BOOL CALLBACK UXTHEME_broadcast_msg_enumchild (HWND hWnd, LPARAM msg)
{
- PostMessageW(hWnd, msg, 0, 0);
+ SendMessageW(hWnd, msg, 0, 0);
return TRUE;
}
}
else
{
- PostMessageW(hWnd, msg, 0, 0);
+ SendMessageW(hWnd, msg, 0, 0);
EnumChildWindows (hWnd, UXTHEME_broadcast_msg_enumchild, msg);
}
return TRUE;
static DWORD query_reg_path (HKEY hKey, LPCWSTR lpszValue,
LPVOID pvData)
{
- DWORD dwRet, dwType, dwUnExpDataLen = MAX_PATH, dwExpDataLen;
+ DWORD dwRet, dwType, dwUnExpDataLen = MAX_PATH * sizeof(WCHAR), dwExpDataLen;
TRACE("(hkey=%p,%s,%p)\n", hKey, debugstr_w(lpszValue),
pvData);
return S_OK;
}
+static BOOL bIsThemeActive(LPCWSTR pszTheme, LPCWSTR pszColor, LPCWSTR pszSize)
+{
+ if (ActiveThemeFile == NULL)
+ return FALSE;
+
+ if (wcscmp(pszTheme, ActiveThemeFile->szThemeFile) != 0)
+ return FALSE;
+
+ if (!pszColor[0])
+ {
+ if (ActiveThemeFile->pszAvailColors != ActiveThemeFile->pszSelectedColor)
+ return FALSE;
+ }
+ else
+ {
+ if (wcscmp(pszColor, ActiveThemeFile->pszSelectedColor) != 0)
+ return FALSE;
+ }
+
+ if (!pszSize[0])
+ {
+ if (ActiveThemeFile->pszAvailSizes != ActiveThemeFile->pszSelectedSize)
+ return FALSE;
+ }
+ else
+ {
+ if (wcscmp(pszSize, ActiveThemeFile->pszSelectedSize) != 0)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/***********************************************************************
* UXTHEME_LoadTheme
*
WCHAR szCurrentTheme[MAX_PATH];
WCHAR szCurrentColor[64];
WCHAR szCurrentSize[64];
+ BOOL bThemeActive = FALSE;
if(bLoad == TRUE)
{
/* Get current theme configuration */
if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
TRACE("Loading theme config\n");
- buffsize = sizeof(tmp)/sizeof(tmp[0]);
+ buffsize = sizeof(tmp);
if(!RegQueryValueExW(hKey, szThemeActive, NULL, NULL, (LPBYTE)tmp, &buffsize)) {
bThemeActive = (tmp[0] != '0');
}
bThemeActive = FALSE;
TRACE("Failed to get ThemeActive: %d\n", GetLastError());
}
- buffsize = sizeof(szCurrentColor)/sizeof(szCurrentColor[0]);
+ buffsize = sizeof(szCurrentColor);
if(RegQueryValueExW(hKey, szColorName, NULL, NULL, (LPBYTE)szCurrentColor, &buffsize))
szCurrentColor[0] = '\0';
- buffsize = sizeof(szCurrentSize)/sizeof(szCurrentSize[0]);
+ buffsize = sizeof(szCurrentSize);
if(RegQueryValueExW(hKey, szSizeName, NULL, NULL, (LPBYTE)szCurrentSize, &buffsize))
szCurrentSize[0] = '\0';
if (query_reg_path (hKey, szDllName, szCurrentTheme))
bThemeActive = FALSE;
}
- if(bThemeActive) {
+ if(bThemeActive)
+ {
+ if( bIsThemeActive(szCurrentTheme, szCurrentColor, szCurrentSize) )
+ {
+ TRACE("Tried to load active theme again\n");
+ return;
+ }
+
/* Make sure the theme requested is actually valid */
hr = MSSTYLES_OpenThemeFile(szCurrentTheme,
szCurrentColor[0]?szCurrentColor:NULL,
WCHAR tmp[2];
HRESULT hr;
- if(tf && !bThemeActive) UXTHEME_BackupSystemMetrics();
+ TRACE("UXTHEME_ApplyTheme\n");
+
+ if (tf && !ActiveThemeFile)
+ {
+ UXTHEME_BackupSystemMetrics();
+ }
+
hr = UXTHEME_SetActiveTheme(tf);
- if(FAILED(hr))
+ if (FAILED(hr))
return hr;
- if(tf) {
- bThemeActive = TRUE;
- }
- else {
+
+ if (!tf)
+ {
UXTHEME_RestoreSystemMetrics();
- bThemeActive = FALSE;
}
TRACE("Writing theme config to registry\n");
if(!RegCreateKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
- tmp[0] = bThemeActive?'1':'0';
+ tmp[0] = ActiveThemeFile?'1':'0';
tmp[1] = '\0';
RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (const BYTE*)tmp, sizeof(WCHAR)*2);
- if(bThemeActive) {
+ if (ActiveThemeFile) {
RegSetValueExW(hKey, szColorName, 0, REG_SZ, (const BYTE*)tf->pszSelectedColor,
(lstrlenW(tf->pszSelectedColor)+1)*sizeof(WCHAR));
RegSetValueExW(hKey, szSizeName, 0, REG_SZ, (const BYTE*)tf->pszSelectedSize,
atSubAppName = GlobalAddAtomW(szSubAppName);
atSubIdList = GlobalAddAtomW(szSubIdList);
atDialogThemeEnabled = GlobalAddAtomW(szDialogThemeEnabled);
- atWndContrext = GlobalAddAtomW(L"ux_WndContext");
+ atWndContext = GlobalAddAtomW(L"ux_WndContext");
}
/***********************************************************************
*/
BOOL WINAPI IsAppThemed(void)
{
- return IsThemeActive();
+ TRACE("\n");
+ SetLastError(ERROR_SUCCESS);
+ return (ActiveThemeFile != NULL);
}
/***********************************************************************
*/
BOOL WINAPI IsThemeActive(void)
{
- TRACE("\n");
+ BOOL bActive;
+ LRESULT Result;
+ HKEY hKey;
+ WCHAR tmp[10];
+ DWORD buffsize;
+
+ TRACE("IsThemeActive\n");
SetLastError(ERROR_SUCCESS);
- return bThemeActive;
+
+ if (ActiveThemeFile)
+ return TRUE;
+
+ if (gbThemeHooksActive)
+ return FALSE;
+
+ bActive = FALSE;
+ Result = RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey);
+ if (Result == ERROR_SUCCESS)
+ {
+ buffsize = sizeof(tmp);
+ if (!RegQueryValueExW(hKey, szThemeActive, NULL, NULL, (LPBYTE)tmp, &buffsize))
+ bActive = (tmp[0] != '0');
+ RegCloseKey(hKey);
+ }
+
+ return bActive;
}
/***********************************************************************
TRACE("(%d)\n", fEnable);
- if(fEnable != bThemeActive) {
+ if (fEnable != (ActiveThemeFile != NULL)) {
if(fEnable)
UXTHEME_BackupSystemMetrics();
else
UXTHEME_RestoreSystemMetrics();
UXTHEME_SaveSystemMetrics ();
- bThemeActive = fEnable;
- if(bThemeActive) szEnabled[0] = '1';
+
+ if (fEnable) szEnabled[0] = '1';
if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (LPBYTE)szEnabled, sizeof(WCHAR));
RegCloseKey(hKey);
{
ATOM oldValue = (ATOM)(size_t)RemovePropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp));
if(oldValue)
+ {
DeleteAtom(oldValue);
- if(pszValue) {
- ATOM atValue = AddAtomW(pszValue);
- if(!atValue
- || !SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp), (LPWSTR)MAKEINTATOM(atValue))) {
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ if(pszValue)
+ {
+ ATOM atValue;
+
+ /* A string with zero lenght is not acceptatble in AddAtomW but we want to support
+ users passing an empty string meaning they want no theme for the specified window */
+ if(!pszValue[0])
+ pszValue = L"0";
+
+ atValue = AddAtomW(pszValue);
+ if (!atValue)
+ {
+ ERR("AddAtomW for %S failed with last error %d!\n", pszValue, GetLastError());
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ if (!SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp), (LPWSTR)MAKEINTATOM(atValue)))
+ {
+ ERR("SetPropW for atom %d failed with last error %d\n", aProp, GetLastError());
if(atValue) DeleteAtom(atValue);
- return hr;
+ return HRESULT_FROM_WIN32(GetLastError());
}
}
return S_OK;
LPCWSTR pszAppName;
LPCWSTR pszUseClassList;
HTHEME hTheme = NULL;
- TRACE("(%p,%s)\n", hwnd, debugstr_w(pszClassList));
-
+ TRACE("(%p,%s, %x)\n", hwnd, debugstr_w(pszClassList), flags);
+
if(!pszClassList)
{
SetLastError(E_POINTER);
if(flags)
FIXME("unhandled flags: %x\n", flags);
- if(bThemeActive)
+ if (ThemeFile)
{
pszAppName = UXTHEME_GetWindowProperty(hwnd, atSubAppName, szAppBuff, sizeof(szAppBuff)/sizeof(szAppBuff[0]));
/* If SetWindowTheme was used on the window, that overrides the class list passed to this function */
pszUseClassList = pszClassList;
if (pszUseClassList)
+ {
+ if (!ThemeFile->classes)
+ MSSTYLES_ParseThemeIni(ThemeFile);
hTheme = MSSTYLES_OpenThemeClass(ThemeFile, pszAppName, pszUseClassList);
+ }
}
+
if(IsWindow(hwnd))
+ {
SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme);
+ }
+ else
+ {
+ SetLastError(E_PROP_ID_UNSUPPORTED);
+ }
+
+ SetLastError(hTheme ? ERROR_SUCCESS : E_PROP_ID_UNSUPPORTED);
+
TRACE(" = %p\n", hTheme);
return hTheme;
}
}
/***********************************************************************
- * OpenThemeDataEx (UXTHEME.16)
+ * OpenThemeDataFromFile (UXTHEME.16)
*/
HTHEME WINAPI OpenThemeDataFromFile(HTHEMEFILE hThemeFile, HWND hwnd, LPCWSTR pszClassList, DWORD flags)
{
- PTHEME_FILE ThemeFile = (PTHEME_FILE)hThemeFile;
-
- MSSTYLES_ParseThemeIni(ThemeFile);
-
- return OpenThemeDataInternal(ThemeFile, hwnd, pszClassList, flags);
+ return OpenThemeDataInternal((PTHEME_FILE)hThemeFile, hwnd, pszClassList, flags);
}
/***********************************************************************
HTHEME WINAPI GetWindowTheme(HWND hwnd)
{
TRACE("(%p)\n", hwnd);
+
if(!IsWindow(hwnd))
+ {
SetLastError(E_HANDLE);
+ return NULL;
+ }
return GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme));
}
HRESULT WINAPI SetWindowTheme(HWND hwnd, LPCWSTR pszSubAppName,
LPCWSTR pszSubIdList)
{
- HRESULT hr;
+ HRESULT hr;
TRACE("(%p,%s,%s)\n", hwnd, debugstr_w(pszSubAppName),
debugstr_w(pszSubIdList));
if(!IsWindow(hwnd))
- return E_HANDLE;
+ return E_HANDLE;
hr = UXTHEME_SetWindowProperty(hwnd, atSubAppName, pszSubAppName);
- if(SUCCEEDED(hr))
- hr = UXTHEME_SetWindowProperty(hwnd, atSubIdList, pszSubIdList);
- if(SUCCEEDED(hr))
- UXTHEME_broadcast_msg (hwnd, WM_THEMECHANGED);
+ if (!SUCCEEDED(hr))
+ return hr;
+
+ hr = UXTHEME_SetWindowProperty(hwnd, atSubIdList, pszSubIdList);
+ if (!SUCCEEDED(hr))
+ return hr;
+
+ UXTHEME_broadcast_msg (hwnd, WM_THEMECHANGED);
return hr;
}
if(ActiveThemeFile == NULL)
return E_PROP_ID_UNSUPPORTED;
- if(pszThemeFileName)
+ if (pszThemeFileName && dwMaxNameChars)
{
cchar = lstrlenW(ActiveThemeFile->szThemeFile) + 1;
if(cchar > dwMaxNameChars)
lstrcpynW(pszThemeFileName, ActiveThemeFile->szThemeFile, cchar);
}
- if(pszColorBuff)
+ if (pszColorBuff && cchMaxColorChars)
{
cchar = lstrlenW(ActiveThemeFile->pszSelectedColor) + 1;
if(cchar > cchMaxColorChars)
lstrcpynW(pszColorBuff, ActiveThemeFile->pszSelectedColor, cchar);
}
- if(pszSizeBuff)
+ if (pszSizeBuff && cchMaxSizeChars)
{
cchar = lstrlenW(ActiveThemeFile->pszSelectedSize) + 1;
if(cchar > cchMaxSizeChars)
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
{
TRACE("(%p)\n", hTheme);
- if(!hTheme)
+ if(!hTheme || hTheme == INVALID_HANDLE_VALUE)
+ return E_HANDLE;
+ if(IsBadReadPtr (hTheme, sizeof(THEME_CLASS))) /* This check is a hack! */
return E_HANDLE;
return MSSTYLES_CloseThemeClass(hTheme);
}
FIXME("%d %d 0x%08x: stub\n", iPartId, iStateId, dwOptions);
if(!hTheme)
return E_HANDLE;
- return ERROR_CALL_NOT_IMPLEMENTED;
+ return E_NOTIMPL;
}
/***********************************************************************
PARSETHEMEINIFILEPROC callback, LPVOID lpData)
{
FIXME("%s %s: stub\n", debugstr_w(pszIniFileName), debugstr_w(pszUnknown));
- return ERROR_CALL_NOT_IMPLEMENTED;
+ return E_NOTIMPL;
}
/**********************************************************************
MSSTYLES_CloseThemeFile(pt);
return S_OK;
}
-
-HRESULT WINAPI DrawNCPreview(HDC hDC,
- DWORD DNCP_Flag,
- LPRECT prcPreview,
- LPCWSTR pszThemeFileName,
- LPCWSTR pszColorName,
- LPCWSTR pszSizeName,
- PNONCLIENTMETRICSW pncMetrics,
- COLORREF* lpaRgbValues)
-{
- return E_NOTIMPL;
-}
-