diff --git a/reactos/dll/win32/uxtheme/msstyles.c b/reactos/dll/win32/uxtheme/msstyles.c index 23b329993e1..d91f62c27c6 100644 --- a/reactos/dll/win32/uxtheme/msstyles.c +++ b/reactos/dll/win32/uxtheme/msstyles.c @@ -81,6 +81,9 @@ HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWST LPWSTR pszSelectedSize = NULL; LPWSTR tmp; + if (!gbThemeHooksActive) + return E_FAIL; + TRACE("Opening %s\n", debugstr_w(lpThemeFile)); hTheme = LoadLibraryExW(lpThemeFile, NULL, LOAD_LIBRARY_AS_DATAFILE); @@ -168,6 +171,9 @@ HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWST (*tf)->pszSelectedColor = pszSelectedColor; (*tf)->pszSelectedSize = pszSelectedSize; (*tf)->dwRefCount = 1; + + TRACE("Theme %p refcount: %d\n", *tf, (*tf)->dwRefCount); + return S_OK; invalid_theme: @@ -183,7 +189,10 @@ invalid_theme: void MSSTYLES_CloseThemeFile(PTHEME_FILE tf) { if(tf) { + tf->dwRefCount--; + TRACE("Theme %p refcount: %d\n", tf, tf->dwRefCount); + if(!tf->dwRefCount) { if(tf->hTheme) FreeLibrary(tf->hTheme); if(tf->classes) { @@ -218,6 +227,7 @@ void MSSTYLES_CloseThemeFile(PTHEME_FILE tf) HRESULT MSSTYLES_ReferenceTheme(PTHEME_FILE tf) { tf->dwRefCount++; + TRACE("Theme %p refcount: %d\n", tf, tf->dwRefCount); return S_OK; } @@ -774,6 +784,7 @@ PTHEME_CLASS MSSTYLES_OpenThemeClass(PTHEME_FILE tf, LPCWSTR pszAppName, LPCWSTR TRACE("Opened app %s, class %s from list %s\n", debugstr_w(cls->szAppName), debugstr_w(cls->szClassName), debugstr_w(pszClassList)); cls->tf = tf; cls->tf->dwRefCount++; + TRACE("Theme %p refcount: %d\n", tf, tf->dwRefCount); } return cls; } diff --git a/reactos/dll/win32/uxtheme/system.c b/reactos/dll/win32/uxtheme/system.c index 40747f6646f..3e90ae76151 100644 --- a/reactos/dll/win32/uxtheme/system.c +++ b/reactos/dll/win32/uxtheme/system.c @@ -50,8 +50,6 @@ static ATOM atSubAppName; static ATOM atSubIdList; ATOM atWndContrext; -static BOOL bThemeActive = FALSE; - static PTHEME_FILE ActiveThemeFile; /***********************************************************************/ @@ -155,6 +153,7 @@ void UXTHEME_LoadTheme(BOOL bLoad) WCHAR szCurrentTheme[MAX_PATH]; WCHAR szCurrentColor[64]; WCHAR szCurrentSize[64]; + BOOL bThemeActive = FALSE; if(bLoad == TRUE) { @@ -472,24 +471,26 @@ static HRESULT UXTHEME_ApplyTheme(PTHEME_FILE tf) WCHAR tmp[2]; HRESULT hr; - if(tf && !bThemeActive) UXTHEME_BackupSystemMetrics(); - hr = UXTHEME_SetActiveTheme(tf); - if(FAILED(hr)) - return hr; - if(tf) { - bThemeActive = TRUE; + if (tf && !ActiveThemeFile) + { + UXTHEME_BackupSystemMetrics(); } - else { + + hr = UXTHEME_SetActiveTheme(tf); + if (FAILED(hr)) + return hr; + + 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, @@ -545,7 +546,9 @@ void UXTHEME_InitSystem(HINSTANCE hInst) */ BOOL WINAPI IsAppThemed(void) { - return IsThemeActive(); + TRACE("\n"); + SetLastError(ERROR_SUCCESS); + return (ActiveThemeFile != NULL); } /*********************************************************************** @@ -553,9 +556,32 @@ BOOL WINAPI IsAppThemed(void) */ BOOL WINAPI IsThemeActive(void) { + BOOL bActive; + LRESULT Result; + HKEY hKey; + WCHAR tmp[10]; + DWORD buffsize; + TRACE("\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)/sizeof(tmp[0]); + if (!RegQueryValueExW(hKey, szThemeActive, NULL, NULL, (LPBYTE)tmp, &buffsize)) + bActive = (tmp[0] != '0'); + RegCloseKey(hKey); + } + + return bActive; } /*********************************************************************** @@ -571,14 +597,14 @@ HRESULT WINAPI EnableTheming(BOOL fEnable) 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); @@ -641,7 +667,7 @@ OpenThemeDataInternal(PTHEME_FILE ThemeFile, HWND hwnd, LPCWSTR pszClassList, DW 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 */ @@ -650,10 +676,24 @@ OpenThemeDataInternal(PTHEME_FILE ThemeFile, HWND hwnd, LPCWSTR pszClassList, DW 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; } @@ -667,15 +707,11 @@ HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags) } /*********************************************************************** - * 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); } /*********************************************************************** @@ -700,8 +736,12 @@ HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist) HTHEME WINAPI GetWindowTheme(HWND hwnd) { TRACE("(%p)\n", hwnd); + if(!IsWindow(hwnd)) + { SetLastError(E_HANDLE); + return NULL; + } return GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme)); } @@ -719,12 +759,16 @@ HRESULT WINAPI SetWindowTheme(HWND hwnd, LPCWSTR 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)) + if (!SUCCEEDED(hr)) + return hr; + + hr = UXTHEME_SetWindowProperty(hwnd, atSubIdList, pszSubIdList); + if (!SUCCEEDED(hr)) + return hr; + UXTHEME_broadcast_msg (hwnd, WM_THEMECHANGED); return hr; } @@ -741,7 +785,7 @@ HRESULT WINAPI GetCurrentThemeName(LPWSTR pszThemeFileName, int dwMaxNameChars, if(ActiveThemeFile == NULL) return E_PROP_ID_UNSUPPORTED; - if(pszThemeFileName) + if (pszThemeFileName && dwMaxNameChars) { cchar = lstrlenW(ActiveThemeFile->szThemeFile) + 1; if(cchar > dwMaxNameChars) @@ -749,7 +793,7 @@ HRESULT WINAPI GetCurrentThemeName(LPWSTR pszThemeFileName, int dwMaxNameChars, lstrcpynW(pszThemeFileName, ActiveThemeFile->szThemeFile, cchar); } - if(pszColorBuff) + if (pszColorBuff && cchMaxColorChars) { cchar = lstrlenW(ActiveThemeFile->pszSelectedColor) + 1; if(cchar > cchMaxColorChars) @@ -757,7 +801,7 @@ HRESULT WINAPI GetCurrentThemeName(LPWSTR pszThemeFileName, int dwMaxNameChars, lstrcpynW(pszColorBuff, ActiveThemeFile->pszSelectedColor, cchar); } - if(pszSizeBuff) + if (pszSizeBuff && cchMaxSizeChars) { cchar = lstrlenW(ActiveThemeFile->pszSelectedSize) + 1; if(cchar > cchMaxSizeChars) diff --git a/reactos/dll/win32/uxtheme/themehooks.c b/reactos/dll/win32/uxtheme/themehooks.c index 1ec92fc2f31..00a72d6613b 100644 --- a/reactos/dll/win32/uxtheme/themehooks.c +++ b/reactos/dll/win32/uxtheme/themehooks.c @@ -11,16 +11,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); - - -extern HINSTANCE hDllInst; - -LRESULT CALLBACK ThemeWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, WNDPROC DefWndProc); - USERAPIHOOK user32ApiHook; BYTE gabDWPmessages[UAHOWP_MAX_SIZE]; BYTE gabMSGPmessages[UAHOWP_MAX_SIZE]; - +BOOL gbThemeHooksActive = FALSE; PWND_CONTEXT ThemeGetWndContext(HWND hWnd) { @@ -266,14 +260,16 @@ int WINAPI ThemeSetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw) BOOL CALLBACK ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah) { - /* Sanity checks for the caller */ if (!puah || State != uahLoadInit) { UXTHEME_LoadTheme(FALSE); ThemeCleanupWndContext(NULL, 0); + gbThemeHooksActive = FALSE; return TRUE; } + gbThemeHooksActive = TRUE; + /* Store the original functions from user32 */ user32ApiHook = *puah; diff --git a/reactos/dll/win32/uxtheme/uxthemep.h b/reactos/dll/win32/uxtheme/uxthemep.h index 72627ffb602..ba8c7e95d49 100644 --- a/reactos/dll/win32/uxtheme/uxthemep.h +++ b/reactos/dll/win32/uxtheme/uxthemep.h @@ -199,14 +199,17 @@ enum SCROLL_HITTEST /* Minimum size of the rectangle between the arrows */ #define SCROLL_MIN_RECT 4 +LRESULT CALLBACK ThemeWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, WNDPROC DefWndProc); void ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT Bar, POINT* pt); VOID NC_TrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt); void ThemeInitDrawContext(PDRAW_CONTEXT pcontext, HWND hWnd, HRGN hRgn); void ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext); PWND_CONTEXT ThemeGetWndContext(HWND hWnd); +extern HINSTANCE hDllInst; extern ATOM atWindowTheme; extern ATOM atWndContrext; +extern BOOL gbThemeHooksActive; void UXTHEME_InitSystem(HINSTANCE hInst); void UXTHEME_LoadTheme(BOOL bLoad);