[UXTHEME]
[reactos.git] / reactos / dll / win32 / uxtheme / system.c
index c834c52..b84e978 100644 (file)
 
 #include "windef.h"
 #include "winbase.h"
-#include "winuser.h"
 #include "wingdi.h"
+#include "winuser.h"
 #include "winreg.h"
+#include "vfwmsgs.h"
 #include "uxtheme.h"
 #include "tmschema.h"
 
@@ -57,17 +58,17 @@ static const WCHAR szDllName[] = {'D','l','l','N','a','m','e','\0'};
 static const WCHAR szIniDocumentation[] = {'d','o','c','u','m','e','n','t','a','t','i','o','n','\0'};
 
 HINSTANCE hDllInst;
-
-DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS;
-ATOM atWindowTheme;
-ATOM atSubAppName;
-ATOM atSubIdList;
 ATOM atDialogThemeEnabled;
 
-BOOL bThemeActive = FALSE;
-WCHAR szCurrentTheme[MAX_PATH];
-WCHAR szCurrentColor[64];
-WCHAR szCurrentSize[64];
+static DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS;
+static ATOM atWindowTheme;
+static ATOM atSubAppName;
+static ATOM atSubIdList;
+
+static BOOL bThemeActive = FALSE;
+static WCHAR szCurrentTheme[MAX_PATH];
+static WCHAR szCurrentColor[64];
+static WCHAR szCurrentSize[64];
 
 /***********************************************************************/
 
@@ -121,21 +122,21 @@ static DWORD query_reg_path (HKEY hKey, LPCWSTR lpszValue,
       WCHAR cNull = '\0';
       nBytesToAlloc = dwUnExpDataLen;
 
-      szData = (LPWSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
+      szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
       RegQueryValueExW (hKey, lpszValue, 0, NULL, (LPBYTE)szData, &nBytesToAlloc);
       dwExpDataLen = ExpandEnvironmentStringsW(szData, &cNull, 1);
       dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
-      LocalFree((HLOCAL) szData);
+      LocalFree(szData);
     }
     else
     {
       nBytesToAlloc = (lstrlenW(pvData) + 1) * sizeof(WCHAR);
-      szData = (LPWSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc );
+      szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc );
       lstrcpyW(szData, pvData);
       dwExpDataLen = ExpandEnvironmentStringsW(szData, pvData, MAX_PATH );
       if (dwExpDataLen > MAX_PATH) dwRet = ERROR_MORE_DATA;
       dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
-      LocalFree((HLOCAL) szData);
+      LocalFree(szData);
     }
   }
 
@@ -165,7 +166,7 @@ static void UXTHEME_LoadTheme(void)
         }
         else {
             bThemeActive = FALSE;
-            TRACE("Failed to get ThemeActive: %ld\n", GetLastError());
+            TRACE("Failed to get ThemeActive: %d\n", GetLastError());
         }
         buffsize = sizeof(szCurrentColor)/sizeof(szCurrentColor[0]);
         if(RegQueryValueExW(hKey, szColorName, NULL, NULL, (LPBYTE)szCurrentColor, &buffsize))
@@ -205,7 +206,7 @@ static void UXTHEME_LoadTheme(void)
     }
     if(!bThemeActive) {
         MSSTYLES_SetActiveTheme(NULL, FALSE);
-        TRACE("Themeing not active\n");
+        TRACE("Theming not active\n");
     }
 }
 
@@ -249,6 +250,12 @@ static const WCHAR strColorKey[] =
     { 'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\',
       'C','o','l','o','r','s',0 };
 static const WCHAR keyFlatMenus[] = { 'F','l','a','t','M','e','n','u', 0};
+static const WCHAR keyGradientCaption[] = { 'G','r','a','d','i','e','n','t',
+                                            'C','a','p','t','i','o','n', 0 };
+static const WCHAR keyNonClientMetrics[] = { 'N','o','n','C','l','i','e','n','t',
+                                             'M','e','t','r','i','c','s',0 };
+static const WCHAR keyIconTitleFont[] = { 'I','c','o','n','T','i','t','l','e',
+                                         'F','o','n','t',0 };
 
 static const struct BackupSysParam
 {
@@ -257,6 +264,7 @@ static const struct BackupSysParam
 } backupSysParams[] = 
 {
     {SPI_GETFLATMENU, SPI_SETFLATMENU, keyFlatMenus},
+    {SPI_GETGRADIENTCAPTIONS, SPI_SETGRADIENTCAPTIONS, keyGradientCaption},
     {-1, -1, 0}
 };
 
@@ -298,8 +306,13 @@ static void UXTHEME_BackupSystemMetrics(void)
                          0, 0, 0, KEY_ALL_ACCESS,
                          0, &hKey, 0) == ERROR_SUCCESS)
     {
+        NONCLIENTMETRICSW ncm;
+        LOGFONTW iconTitleFont;
+        
+        /* back up colors */
         save_sys_colors (hKey);
     
+        /* back up "other" settings */
         while (bsp->spiGet >= 0)
         {
             DWORD value;
@@ -310,6 +323,18 @@ static void UXTHEME_BackupSystemMetrics(void)
         
             bsp++;
         }
+        
+       /* back up non-client metrics */
+        memset (&ncm, 0, sizeof (ncm));
+        ncm.cbSize = sizeof (ncm);
+        SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof (ncm), &ncm, 0);
+        RegSetValueExW (hKey, keyNonClientMetrics, 0, REG_BINARY, (LPBYTE)&ncm,
+            sizeof (ncm));
+       memset (&iconTitleFont, 0, sizeof (iconTitleFont));
+       SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (iconTitleFont),
+           &iconTitleFont, 0);
+       RegSetValueExW (hKey, keyIconTitleFont, 0, REG_BINARY, 
+           (LPBYTE)&iconTitleFont, sizeof (iconTitleFont));
     
         RegCloseKey (hKey);
     }
@@ -368,23 +393,49 @@ static void UXTHEME_RestoreSystemMetrics(void)
             if (RegQueryValueExW (hKey, bsp->keyName, 0,
                 &type, (LPBYTE)&value, &count) == ERROR_SUCCESS)
             {
-                SystemParametersInfoW (bsp->spiSet, 0, (LPVOID)value,
-                    SPIF_UPDATEINIFILE);
+                SystemParametersInfoW (bsp->spiSet, 0, UlongToPtr(value), SPIF_UPDATEINIFILE);
             }
         
             bsp++;
         }
     
+        /* read backed-up non-client metrics */
+        {
+            NONCLIENTMETRICSW ncm;
+            LOGFONTW iconTitleFont;
+            DWORD count = sizeof(ncm);
+            DWORD type;
+            
+           if (RegQueryValueExW (hKey, keyNonClientMetrics, 0,
+               &type, (LPBYTE)&ncm, &count) == ERROR_SUCCESS)
+           {
+               SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, 
+                    count, &ncm, SPIF_UPDATEINIFILE);
+           }
+           
+            count = sizeof(iconTitleFont);
+            
+           if (RegQueryValueExW (hKey, keyIconTitleFont, 0,
+               &type, (LPBYTE)&iconTitleFont, &count) == ERROR_SUCCESS)
+           {
+               SystemParametersInfoW (SPI_SETICONTITLELOGFONT, 
+                    count, &iconTitleFont, SPIF_UPDATEINIFILE);
+           }
+       }
       
         RegCloseKey (hKey);
     }
 }
 
 /* Make system settings persistent, so they're in effect even w/o uxtheme 
- * loaded */
+ * loaded.
+ * For efficiency reasons, only the last SystemParametersInfoW sets
+ * SPIF_SENDWININICHANGE */
 static void UXTHEME_SaveSystemMetrics(void)
 {
     const struct BackupSysParam* bsp = backupSysParams;
+    NONCLIENTMETRICSW ncm;
+    LOGFONTW iconTitleFont;
 
     save_sys_colors (HKEY_CURRENT_USER);
 
@@ -393,12 +444,21 @@ static void UXTHEME_SaveSystemMetrics(void)
         DWORD value;
         
         SystemParametersInfoW (bsp->spiGet, 0, &value, 0);
-        SystemParametersInfoW (bsp->spiSet, 0, (LPVOID)value,
-            SPIF_UPDATEINIFILE);
-    
+        SystemParametersInfoW (bsp->spiSet, 0, UlongToPtr(value), SPIF_UPDATEINIFILE);
         bsp++;
     }
-
+    
+    memset (&ncm, 0, sizeof (ncm));
+    ncm.cbSize = sizeof (ncm);
+    SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof (ncm), &ncm, 0);
+    SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, sizeof (ncm), &ncm,
+        SPIF_UPDATEINIFILE);
+
+    memset (&iconTitleFont, 0, sizeof (iconTitleFont));
+    SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (iconTitleFont),
+        &iconTitleFont, 0);
+    SystemParametersInfoW (SPI_SETICONTITLELOGFONT, sizeof (iconTitleFont),
+        &iconTitleFont, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
 }
 
 /***********************************************************************
@@ -406,13 +466,13 @@ static void UXTHEME_SaveSystemMetrics(void)
  *
  * Change the current active theme
  */
-HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf)
+static HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf)
 {
     HKEY hKey;
     WCHAR tmp[2];
     HRESULT hr;
 
-    if(tf) UXTHEME_BackupSystemMetrics();
+    if(tf && !bThemeActive) UXTHEME_BackupSystemMetrics();
     hr = MSSTYLES_SetActiveTheme(tf, TRUE);
     if(FAILED(hr))
         return hr;
@@ -501,6 +561,7 @@ BOOL WINAPI IsAppThemed(void)
 BOOL WINAPI IsThemeActive(void)
 {
     TRACE("\n");
+    SetLastError(ERROR_SUCCESS);
     return bThemeActive;
 }
 
@@ -540,15 +601,15 @@ HRESULT WINAPI EnableTheming(BOOL fEnable)
  * I'm using atoms as there may be large numbers of duplicated strings
  * and they do the work of keeping memory down as a cause of that quite nicely
  */
-HRESULT UXTHEME_SetWindowProperty(HWND hwnd, ATOM aProp, LPCWSTR pszValue)
+static HRESULT UXTHEME_SetWindowProperty(HWND hwnd, ATOM aProp, LPCWSTR pszValue)
 {
-    ATOM oldValue = (ATOM)(size_t)RemovePropW(hwnd, MAKEINTATOMW(aProp));
+    ATOM oldValue = (ATOM)(size_t)RemovePropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp));
     if(oldValue)
         DeleteAtom(oldValue);
     if(pszValue) {
         ATOM atValue = AddAtomW(pszValue);
         if(!atValue
-           || !SetPropW(hwnd, MAKEINTATOMW(aProp), (LPWSTR)MAKEINTATOMW(atValue))) {
+           || !SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp), (LPWSTR)MAKEINTATOM(atValue))) {
             HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
             if(atValue) DeleteAtom(atValue);
             return hr;
@@ -557,9 +618,9 @@ HRESULT UXTHEME_SetWindowProperty(HWND hwnd, ATOM aProp, LPCWSTR pszValue)
     return S_OK;
 }
 
-LPWSTR UXTHEME_GetWindowProperty(HWND hwnd, ATOM aProp, LPWSTR pszBuffer, int dwLen)
+static LPWSTR UXTHEME_GetWindowProperty(HWND hwnd, ATOM aProp, LPWSTR pszBuffer, int dwLen)
 {
-    ATOM atValue = (ATOM)(size_t)GetPropW(hwnd, MAKEINTATOMW(aProp));
+    ATOM atValue = (ATOM)(size_t)GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp));
     if(atValue) {
         if(GetAtomNameW(atValue, pszBuffer, dwLen))
             return pszBuffer;
@@ -578,7 +639,7 @@ HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR pszClassList)
     LPCWSTR pszAppName;
     LPCWSTR pszUseClassList;
     HTHEME hTheme = NULL;
-    TRACE("(%p,%s)", hwnd, debugstr_w(pszClassList));
+    TRACE("(%p,%s)\n", hwnd, debugstr_w(pszClassList));
 
     if(bThemeActive)
     {
@@ -592,7 +653,7 @@ HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR pszClassList)
             hTheme = MSSTYLES_OpenThemeClass(pszAppName, pszUseClassList);
     }
     if(IsWindow(hwnd))
-        SetPropW(hwnd, MAKEINTATOMW(atWindowTheme), hTheme);
+        SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme);
     TRACE(" = %p\n", hTheme);
     return hTheme;
 }
@@ -611,7 +672,7 @@ HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR pszClassList)
 HTHEME WINAPI GetWindowTheme(HWND hwnd)
 {
     TRACE("(%p)\n", hwnd);
-    return GetPropW(hwnd, MAKEINTATOMW(atWindowTheme));
+    return GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme));
 }
 
 /***********************************************************************
@@ -661,7 +722,7 @@ DWORD WINAPI GetThemeAppProperties(void)
  */
 void WINAPI SetThemeAppProperties(DWORD dwFlags)
 {
-    TRACE("(0x%08lx)\n", dwFlags);
+    TRACE("(0x%08x)\n", dwFlags);
     dwThemeAppProperties = dwFlags;
 }
 
@@ -684,7 +745,7 @@ HRESULT WINAPI HitTestThemeBackground(HTHEME hTheme, HDC hdc, int iPartId,
                                      const RECT *pRect, HRGN hrgn,
                                      POINT ptTest, WORD *pwHitTestCode)
 {
-    FIXME("%d %d 0x%08lx: stub\n", iPartId, iStateId, dwOptions);
+    FIXME("%d %d 0x%08x: stub\n", iPartId, iStateId, dwOptions);
     if(!hTheme)
         return E_HANDLE;
     return ERROR_CALL_NOT_IMPLEMENTED;
@@ -777,7 +838,7 @@ HRESULT WINAPI GetThemeDocumentationProperty(LPCWSTR pszThemeName,
  * RETURNS
  *     some kind of status flag
  */
-DWORD WINAPI QueryThemeServices()
+DWORD WINAPI QueryThemeServices(void)
 {
     FIXME("stub\n");
     return 3; /* This is what is returned under XP in most cases */
@@ -803,7 +864,7 @@ HRESULT WINAPI OpenThemeFile(LPCWSTR pszThemeFileName, LPCWSTR pszColorName,
                              LPCWSTR pszSizeName, HTHEMEFILE *hThemeFile,
                              DWORD unknown)
 {
-    TRACE("(%s,%s,%s,%p,%ld)\n", debugstr_w(pszThemeFileName),
+    TRACE("(%s,%s,%s,%p,%d)\n", debugstr_w(pszThemeFileName),
           debugstr_w(pszColorName), debugstr_w(pszSizeName),
           hThemeFile, unknown);
     return MSSTYLES_OpenThemeFile(pszThemeFileName, pszColorName, pszSizeName, (PTHEME_FILE*)hThemeFile);
@@ -850,7 +911,7 @@ HRESULT WINAPI CloseThemeFile(HTHEMEFILE hThemeFile)
  * 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
+ *   the function fails returning invalid parameter... very strange
  */
 HRESULT WINAPI ApplyTheme(HTHEMEFILE hThemeFile, char *unknown, HWND hWnd)
 {
@@ -883,7 +944,7 @@ HRESULT WINAPI GetThemeDefaults(LPCWSTR pszThemeFileName, LPWSTR pszColorName,
 {
     PTHEME_FILE pt;
     HRESULT hr;
-    TRACE("(%s,%p,%ld,%p,%ld)\n", debugstr_w(pszThemeFileName),
+    TRACE("(%s,%p,%d,%p,%d)\n", debugstr_w(pszThemeFileName),
           pszColorName, dwColorNameLen,
           pszSizeName, dwSizeNameLen);
 
@@ -1002,7 +1063,7 @@ HRESULT WINAPI EnumThemeColors(LPWSTR pszThemeFileName, LPWSTR pszSizeName,
     HRESULT hr;
     LPWSTR tmp;
     UINT resourceId = dwColorNum + 1000;
-    TRACE("(%s,%s,%ld)\n", debugstr_w(pszThemeFileName),
+    TRACE("(%s,%s,%d)\n", debugstr_w(pszThemeFileName),
           debugstr_w(pszSizeName), dwColorNum);
 
     hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, pszSizeName, &pt);
@@ -1062,7 +1123,7 @@ HRESULT WINAPI EnumThemeSizes(LPWSTR pszThemeFileName, LPWSTR pszColorName,
     HRESULT hr;
     LPWSTR tmp;
     UINT resourceId = dwSizeNum + 3000;
-    TRACE("(%s,%s,%ld)\n", debugstr_w(pszThemeFileName),
+    TRACE("(%s,%s,%d)\n", debugstr_w(pszThemeFileName),
           debugstr_w(pszColorName), dwSizeNum);
 
     hr = MSSTYLES_OpenThemeFile(pszThemeFileName, pszColorName, NULL, &pt);
@@ -1106,7 +1167,7 @@ HRESULT WINAPI EnumThemeSizes(LPWSTR pszThemeFileName, LPWSTR pszColorName,
  *     0x800706488 (Unknown property) when enumeration is canceled from callback
  *
  * NOTES
- * When pszUnknown is NULL the callback is never called, the value does not seem to surve
+ * When pszUnknown is NULL the callback is never called, the value does not seem to serve
  * any other purpose
  */
 HRESULT WINAPI ParseThemeIniFile(LPCWSTR pszIniFileName, LPWSTR pszUnknown,