ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

system.c
Go to the documentation of this file.
00001 /*
00002  * Win32 5.1 Theme system
00003  *
00004  * Copyright (C) 2003 Kevin Koltzau
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "uxthemep.h"
00022 #include "wine/debug.h"
00023 
00024 WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
00025 
00026 /***********************************************************************
00027  * Defines and global variables
00028  */
00029 
00030 static const WCHAR szThemeManager[] = {
00031     'S','o','f','t','w','a','r','e','\\',
00032     'M','i','c','r','o','s','o','f','t','\\',
00033     'W','i','n','d','o','w','s','\\',
00034     'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
00035     'T','h','e','m','e','M','a','n','a','g','e','r','\0'
00036 };
00037 static const WCHAR szThemeActive[] = {'T','h','e','m','e','A','c','t','i','v','e','\0'};
00038 static const WCHAR szSizeName[] = {'S','i','z','e','N','a','m','e','\0'};
00039 static const WCHAR szColorName[] = {'C','o','l','o','r','N','a','m','e','\0'};
00040 static const WCHAR szDllName[] = {'D','l','l','N','a','m','e','\0'};
00041 
00042 static const WCHAR szIniDocumentation[] = {'d','o','c','u','m','e','n','t','a','t','i','o','n','\0'};
00043 
00044 HINSTANCE hDllInst;
00045 ATOM atDialogThemeEnabled;
00046 
00047 static DWORD dwThemeAppProperties = STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS;
00048 ATOM atWindowTheme;
00049 static ATOM atSubAppName;
00050 static ATOM atSubIdList;
00051 ATOM atWndContrext;
00052 
00053 static BOOL bThemeActive = FALSE;
00054 static WCHAR szCurrentTheme[MAX_PATH];
00055 static WCHAR szCurrentColor[64];
00056 static WCHAR szCurrentSize[64];
00057 
00058 /***********************************************************************/
00059 
00060 static BOOL CALLBACK UXTHEME_broadcast_msg_enumchild (HWND hWnd, LPARAM msg)
00061 {
00062     PostMessageW(hWnd, msg, 0, 0);
00063     return TRUE;
00064 }
00065 
00066 /* Broadcast a message to *all* windows, including children */
00067 BOOL CALLBACK UXTHEME_broadcast_msg (HWND hWnd, LPARAM msg)
00068 {
00069     if (hWnd == NULL)
00070     {
00071     EnumWindows (UXTHEME_broadcast_msg, msg);
00072     }
00073     else
00074     {
00075     PostMessageW(hWnd, msg, 0, 0);
00076     EnumChildWindows (hWnd, UXTHEME_broadcast_msg_enumchild, msg);
00077     }
00078     return TRUE;
00079 }
00080 
00081 /* At the end of the day this is a subset of what SHRegGetPath() does - copied
00082  * here to avoid linking against shlwapi. */
00083 static DWORD query_reg_path (HKEY hKey, LPCWSTR lpszValue,
00084                              LPVOID pvData)
00085 {
00086   DWORD dwRet, dwType, dwUnExpDataLen = MAX_PATH, dwExpDataLen;
00087 
00088   TRACE("(hkey=%p,%s,%p)\n", hKey, debugstr_w(lpszValue),
00089         pvData);
00090 
00091   dwRet = RegQueryValueExW(hKey, lpszValue, 0, &dwType, pvData, &dwUnExpDataLen);
00092   if (dwRet!=ERROR_SUCCESS && dwRet!=ERROR_MORE_DATA)
00093       return dwRet;
00094 
00095   if (dwType == REG_EXPAND_SZ)
00096   {
00097     DWORD nBytesToAlloc;
00098 
00099     /* Expand type REG_EXPAND_SZ into REG_SZ */
00100     LPWSTR szData;
00101 
00102     /* If the caller didn't supply a buffer or the buffer is too small we have
00103      * to allocate our own
00104      */
00105     if (dwRet == ERROR_MORE_DATA)
00106     {
00107       WCHAR cNull = '\0';
00108       nBytesToAlloc = dwUnExpDataLen;
00109 
00110       szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
00111       RegQueryValueExW (hKey, lpszValue, 0, NULL, (LPBYTE)szData, &nBytesToAlloc);
00112       dwExpDataLen = ExpandEnvironmentStringsW(szData, &cNull, 1);
00113       dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
00114       LocalFree(szData);
00115     }
00116     else
00117     {
00118       nBytesToAlloc = (lstrlenW(pvData) + 1) * sizeof(WCHAR);
00119       szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc );
00120       lstrcpyW(szData, pvData);
00121       dwExpDataLen = ExpandEnvironmentStringsW(szData, pvData, MAX_PATH );
00122       if (dwExpDataLen > MAX_PATH) dwRet = ERROR_MORE_DATA;
00123       dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
00124       LocalFree(szData);
00125     }
00126   }
00127 
00128   return dwRet;
00129 }
00130 
00131 /***********************************************************************
00132  *      UXTHEME_LoadTheme
00133  *
00134  * Set the current active theme from the registry
00135  */
00136 void UXTHEME_LoadTheme(BOOL bLoad)
00137 {
00138     HKEY hKey;
00139     DWORD buffsize;
00140     HRESULT hr;
00141     WCHAR tmp[10];
00142     PTHEME_FILE pt;
00143 
00144     if(bLoad == TRUE) 
00145     {
00146         /* Get current theme configuration */
00147         if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
00148             TRACE("Loading theme config\n");
00149             buffsize = sizeof(tmp)/sizeof(tmp[0]);
00150             if(!RegQueryValueExW(hKey, szThemeActive, NULL, NULL, (LPBYTE)tmp, &buffsize)) {
00151                 bThemeActive = (tmp[0] != '0');
00152             }
00153             else {
00154                 bThemeActive = FALSE;
00155                 TRACE("Failed to get ThemeActive: %d\n", GetLastError());
00156             }
00157             buffsize = sizeof(szCurrentColor)/sizeof(szCurrentColor[0]);
00158             if(RegQueryValueExW(hKey, szColorName, NULL, NULL, (LPBYTE)szCurrentColor, &buffsize))
00159                 szCurrentColor[0] = '\0';
00160             buffsize = sizeof(szCurrentSize)/sizeof(szCurrentSize[0]);
00161             if(RegQueryValueExW(hKey, szSizeName, NULL, NULL, (LPBYTE)szCurrentSize, &buffsize))
00162                 szCurrentSize[0] = '\0';
00163             if (query_reg_path (hKey, szDllName, szCurrentTheme))
00164                 szCurrentTheme[0] = '\0';
00165             RegCloseKey(hKey);
00166         }
00167         else
00168             TRACE("Failed to open theme registry key\n");
00169     }
00170     else
00171     {
00172         bThemeActive = FALSE;
00173     }
00174 
00175     if(bThemeActive) {
00176         /* Make sure the theme requested is actually valid */
00177         hr = MSSTYLES_OpenThemeFile(szCurrentTheme,
00178                                     szCurrentColor[0]?szCurrentColor:NULL,
00179                                     szCurrentSize[0]?szCurrentSize:NULL,
00180                                     &pt);
00181         if(FAILED(hr)) {
00182             bThemeActive = FALSE;
00183             szCurrentTheme[0] = '\0';
00184             szCurrentColor[0] = '\0';
00185             szCurrentSize[0] = '\0';
00186         }
00187         else {
00188             /* Make sure the global color & size match the theme */
00189             lstrcpynW(szCurrentColor, pt->pszSelectedColor, sizeof(szCurrentColor)/sizeof(szCurrentColor[0]));
00190             lstrcpynW(szCurrentSize, pt->pszSelectedSize, sizeof(szCurrentSize)/sizeof(szCurrentSize[0]));
00191 
00192             MSSTYLES_SetActiveTheme(pt, FALSE);
00193             TRACE("Theme active: %s %s %s\n", debugstr_w(szCurrentTheme),
00194                 debugstr_w(szCurrentColor), debugstr_w(szCurrentSize));
00195             MSSTYLES_CloseThemeFile(pt);
00196         }
00197     }
00198     if(!bThemeActive) {
00199         MSSTYLES_SetActiveTheme(NULL, FALSE);
00200         TRACE("Theming not active\n");
00201     }
00202 }
00203 
00204 /***********************************************************************/
00205 
00206 static const char * const SysColorsNames[] =
00207 {
00208     "Scrollbar",                /* COLOR_SCROLLBAR */
00209     "Background",               /* COLOR_BACKGROUND */
00210     "ActiveTitle",              /* COLOR_ACTIVECAPTION */
00211     "InactiveTitle",            /* COLOR_INACTIVECAPTION */
00212     "Menu",                     /* COLOR_MENU */
00213     "Window",                   /* COLOR_WINDOW */
00214     "WindowFrame",              /* COLOR_WINDOWFRAME */
00215     "MenuText",                 /* COLOR_MENUTEXT */
00216     "WindowText",               /* COLOR_WINDOWTEXT */
00217     "TitleText",                /* COLOR_CAPTIONTEXT */
00218     "ActiveBorder",             /* COLOR_ACTIVEBORDER */
00219     "InactiveBorder",           /* COLOR_INACTIVEBORDER */
00220     "AppWorkSpace",             /* COLOR_APPWORKSPACE */
00221     "Hilight",                  /* COLOR_HIGHLIGHT */
00222     "HilightText",              /* COLOR_HIGHLIGHTTEXT */
00223     "ButtonFace",               /* COLOR_BTNFACE */
00224     "ButtonShadow",             /* COLOR_BTNSHADOW */
00225     "GrayText",                 /* COLOR_GRAYTEXT */
00226     "ButtonText",               /* COLOR_BTNTEXT */
00227     "InactiveTitleText",        /* COLOR_INACTIVECAPTIONTEXT */
00228     "ButtonHilight",            /* COLOR_BTNHIGHLIGHT */
00229     "ButtonDkShadow",           /* COLOR_3DDKSHADOW */
00230     "ButtonLight",              /* COLOR_3DLIGHT */
00231     "InfoText",                 /* COLOR_INFOTEXT */
00232     "InfoWindow",               /* COLOR_INFOBK */
00233     "ButtonAlternateFace",      /* COLOR_ALTERNATEBTNFACE */
00234     "HotTrackingColor",         /* COLOR_HOTLIGHT */
00235     "GradientActiveTitle",      /* COLOR_GRADIENTACTIVECAPTION */
00236     "GradientInactiveTitle",    /* COLOR_GRADIENTINACTIVECAPTION */
00237     "MenuHilight",              /* COLOR_MENUHILIGHT */
00238     "MenuBar",                  /* COLOR_MENUBAR */
00239 };
00240 static const WCHAR strColorKey[] = 
00241     { 'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\',
00242       'C','o','l','o','r','s',0 };
00243 static const WCHAR keyFlatMenus[] = { 'F','l','a','t','M','e','n','u', 0};
00244 static const WCHAR keyGradientCaption[] = { 'G','r','a','d','i','e','n','t',
00245                                             'C','a','p','t','i','o','n', 0 };
00246 static const WCHAR keyNonClientMetrics[] = { 'N','o','n','C','l','i','e','n','t',
00247                                              'M','e','t','r','i','c','s',0 };
00248 static const WCHAR keyIconTitleFont[] = { 'I','c','o','n','T','i','t','l','e',
00249                       'F','o','n','t',0 };
00250 
00251 static const struct BackupSysParam
00252 {
00253     int spiGet, spiSet;
00254     const WCHAR* keyName;
00255 } backupSysParams[] = 
00256 {
00257     {SPI_GETFLATMENU, SPI_SETFLATMENU, keyFlatMenus},
00258     {SPI_GETGRADIENTCAPTIONS, SPI_SETGRADIENTCAPTIONS, keyGradientCaption},
00259     {-1, -1, 0}
00260 };
00261 
00262 #define NUM_SYS_COLORS     (COLOR_MENUBAR+1)
00263 
00264 static void save_sys_colors (HKEY baseKey)
00265 {
00266     char colorStr[13];
00267     HKEY hKey;
00268     int i;
00269 
00270     if (RegCreateKeyExW( baseKey, strColorKey,
00271                          0, 0, 0, KEY_ALL_ACCESS,
00272                          0, &hKey, 0 ) == ERROR_SUCCESS)
00273     {
00274         for (i = 0; i < NUM_SYS_COLORS; i++)
00275         {
00276             COLORREF col = GetSysColor (i);
00277         
00278             sprintf (colorStr, "%d %d %d", 
00279                 GetRValue (col), GetGValue (col), GetBValue (col));
00280 
00281             RegSetValueExA (hKey, SysColorsNames[i], 0, REG_SZ, 
00282                 (BYTE*)colorStr, strlen (colorStr)+1);
00283         }
00284         RegCloseKey (hKey);
00285     }
00286 }
00287 
00288 /* Before activating a theme, query current system colors, certain settings 
00289  * and backup them in the registry, so they can be restored when the theme 
00290  * is deactivated */
00291 static void UXTHEME_BackupSystemMetrics(void)
00292 {
00293     HKEY hKey;
00294     const struct BackupSysParam* bsp = backupSysParams;
00295 
00296     if (RegCreateKeyExW( HKEY_CURRENT_USER, szThemeManager,
00297                          0, 0, 0, KEY_ALL_ACCESS,
00298                          0, &hKey, 0) == ERROR_SUCCESS)
00299     {
00300         NONCLIENTMETRICSW ncm;
00301         LOGFONTW iconTitleFont;
00302         
00303         /* back up colors */
00304         save_sys_colors (hKey);
00305     
00306         /* back up "other" settings */
00307         while (bsp->spiGet >= 0)
00308         {
00309             DWORD value;
00310             
00311             SystemParametersInfoW (bsp->spiGet, 0, &value, 0);
00312             RegSetValueExW (hKey, bsp->keyName, 0, REG_DWORD, 
00313                 (LPBYTE)&value, sizeof (value));
00314         
00315             bsp++;
00316         }
00317         
00318     /* back up non-client metrics */
00319         memset (&ncm, 0, sizeof (ncm));
00320         ncm.cbSize = sizeof (ncm);
00321         SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof (ncm), &ncm, 0);
00322         RegSetValueExW (hKey, keyNonClientMetrics, 0, REG_BINARY, (LPBYTE)&ncm,
00323             sizeof (ncm));
00324     memset (&iconTitleFont, 0, sizeof (iconTitleFont));
00325     SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (iconTitleFont),
00326         &iconTitleFont, 0);
00327     RegSetValueExW (hKey, keyIconTitleFont, 0, REG_BINARY, 
00328         (LPBYTE)&iconTitleFont, sizeof (iconTitleFont));
00329     
00330         RegCloseKey (hKey);
00331     }
00332 }
00333 
00334 /* Read back old settings after a theme was deactivated */
00335 static void UXTHEME_RestoreSystemMetrics(void)
00336 {
00337     HKEY hKey;
00338     const struct BackupSysParam* bsp = backupSysParams;
00339 
00340     if (RegOpenKeyExW (HKEY_CURRENT_USER, szThemeManager,
00341                        0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) 
00342     {
00343         HKEY colorKey;
00344     
00345         /* read backed-up colors */
00346         if (RegOpenKeyExW (hKey, strColorKey,
00347                            0, KEY_QUERY_VALUE, &colorKey) == ERROR_SUCCESS) 
00348         {
00349             int i;
00350             COLORREF sysCols[NUM_SYS_COLORS];
00351             int sysColsIndices[NUM_SYS_COLORS];
00352             int sysColCount = 0;
00353         
00354             for (i = 0; i < NUM_SYS_COLORS; i++)
00355             {
00356                 DWORD type;
00357                 char colorStr[13];
00358                 DWORD count = sizeof(colorStr);
00359             
00360                 if (RegQueryValueExA (colorKey, SysColorsNames[i], 0,
00361                     &type, (LPBYTE) colorStr, &count) == ERROR_SUCCESS)
00362                 {
00363                     int r, g, b;
00364                     if (sscanf (colorStr, "%d %d %d", &r, &g, &b) == 3)
00365                     {
00366                         sysColsIndices[sysColCount] = i;
00367                         sysCols[sysColCount] = RGB(r, g, b);
00368                         sysColCount++;
00369                     }
00370                 }
00371             }
00372             RegCloseKey (colorKey);
00373           
00374             SetSysColors (sysColCount, sysColsIndices, sysCols);
00375         }
00376     
00377         /* read backed-up other settings */
00378         while (bsp->spiGet >= 0)
00379         {
00380             DWORD value;
00381             DWORD count = sizeof(value);
00382             DWORD type;
00383             
00384             if (RegQueryValueExW (hKey, bsp->keyName, 0,
00385                 &type, (LPBYTE)&value, &count) == ERROR_SUCCESS)
00386             {
00387                 SystemParametersInfoW (bsp->spiSet, 0, UlongToPtr(value), SPIF_UPDATEINIFILE);
00388             }
00389         
00390             bsp++;
00391         }
00392     
00393         /* read backed-up non-client metrics */
00394         {
00395             NONCLIENTMETRICSW ncm;
00396             LOGFONTW iconTitleFont;
00397             DWORD count = sizeof(ncm);
00398             DWORD type;
00399             
00400         if (RegQueryValueExW (hKey, keyNonClientMetrics, 0,
00401         &type, (LPBYTE)&ncm, &count) == ERROR_SUCCESS)
00402         {
00403         SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, 
00404                     count, &ncm, SPIF_UPDATEINIFILE);
00405         }
00406         
00407             count = sizeof(iconTitleFont);
00408             
00409         if (RegQueryValueExW (hKey, keyIconTitleFont, 0,
00410         &type, (LPBYTE)&iconTitleFont, &count) == ERROR_SUCCESS)
00411         {
00412         SystemParametersInfoW (SPI_SETICONTITLELOGFONT, 
00413                     count, &iconTitleFont, SPIF_UPDATEINIFILE);
00414         }
00415     }
00416       
00417         RegCloseKey (hKey);
00418     }
00419 }
00420 
00421 /* Make system settings persistent, so they're in effect even w/o uxtheme 
00422  * loaded.
00423  * For efficiency reasons, only the last SystemParametersInfoW sets
00424  * SPIF_SENDWININICHANGE */
00425 static void UXTHEME_SaveSystemMetrics(void)
00426 {
00427     const struct BackupSysParam* bsp = backupSysParams;
00428     NONCLIENTMETRICSW ncm;
00429     LOGFONTW iconTitleFont;
00430 
00431     save_sys_colors (HKEY_CURRENT_USER);
00432 
00433     while (bsp->spiGet >= 0)
00434     {
00435         DWORD value;
00436         
00437         SystemParametersInfoW (bsp->spiGet, 0, &value, 0);
00438         SystemParametersInfoW (bsp->spiSet, 0, UlongToPtr(value), SPIF_UPDATEINIFILE);
00439         bsp++;
00440     }
00441     
00442     memset (&ncm, 0, sizeof (ncm));
00443     ncm.cbSize = sizeof (ncm);
00444     SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof (ncm), &ncm, 0);
00445     SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, sizeof (ncm), &ncm,
00446         SPIF_UPDATEINIFILE);
00447 
00448     memset (&iconTitleFont, 0, sizeof (iconTitleFont));
00449     SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (iconTitleFont),
00450         &iconTitleFont, 0);
00451     SystemParametersInfoW (SPI_SETICONTITLELOGFONT, sizeof (iconTitleFont),
00452         &iconTitleFont, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
00453 }
00454 
00455 /***********************************************************************
00456  *      UXTHEME_SetActiveTheme
00457  *
00458  * Change the current active theme
00459  */
00460 static HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf)
00461 {
00462     HKEY hKey;
00463     WCHAR tmp[2];
00464     HRESULT hr;
00465 
00466     if(tf && !bThemeActive) UXTHEME_BackupSystemMetrics();
00467     hr = MSSTYLES_SetActiveTheme(tf, TRUE);
00468     if(FAILED(hr))
00469         return hr;
00470     if(tf) {
00471         bThemeActive = TRUE;
00472         lstrcpynW(szCurrentTheme, tf->szThemeFile, sizeof(szCurrentTheme)/sizeof(szCurrentTheme[0]));
00473         lstrcpynW(szCurrentColor, tf->pszSelectedColor, sizeof(szCurrentColor)/sizeof(szCurrentColor[0]));
00474         lstrcpynW(szCurrentSize, tf->pszSelectedSize, sizeof(szCurrentSize)/sizeof(szCurrentSize[0]));
00475     }
00476     else {
00477         UXTHEME_RestoreSystemMetrics();
00478         bThemeActive = FALSE;
00479         szCurrentTheme[0] = '\0';
00480         szCurrentColor[0] = '\0';
00481         szCurrentSize[0] = '\0';
00482     }
00483 
00484     TRACE("Writing theme config to registry\n");
00485     if(!RegCreateKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
00486         tmp[0] = bThemeActive?'1':'0';
00487         tmp[1] = '\0';
00488         RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (const BYTE*)tmp, sizeof(WCHAR)*2);
00489         if(bThemeActive) {
00490             RegSetValueExW(hKey, szColorName, 0, REG_SZ, (const BYTE*)szCurrentColor, 
00491         (lstrlenW(szCurrentColor)+1)*sizeof(WCHAR));
00492             RegSetValueExW(hKey, szSizeName, 0, REG_SZ, (const BYTE*)szCurrentSize, 
00493         (lstrlenW(szCurrentSize)+1)*sizeof(WCHAR));
00494             RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*)szCurrentTheme, 
00495         (lstrlenW(szCurrentTheme)+1)*sizeof(WCHAR));
00496         }
00497         else {
00498             RegDeleteValueW(hKey, szColorName);
00499             RegDeleteValueW(hKey, szSizeName);
00500             RegDeleteValueW(hKey, szDllName);
00501 
00502         }
00503         RegCloseKey(hKey);
00504     }
00505     else
00506         TRACE("Failed to open theme registry key\n");
00507     
00508     UXTHEME_SaveSystemMetrics ();
00509     
00510     return hr;
00511 }
00512 
00513 /***********************************************************************
00514  *      UXTHEME_InitSystem
00515  */
00516 void UXTHEME_InitSystem(HINSTANCE hInst)
00517 {
00518     static const WCHAR szWindowTheme[] = {
00519         'u','x','_','t','h','e','m','e','\0'
00520     };
00521     static const WCHAR szSubAppName[] = {
00522         'u','x','_','s','u','b','a','p','p','\0'
00523     };
00524     static const WCHAR szSubIdList[] = {
00525         'u','x','_','s','u','b','i','d','l','s','t','\0'
00526     };
00527     static const WCHAR szDialogThemeEnabled[] = {
00528         'u','x','_','d','i','a','l','o','g','t','h','e','m','e','\0'
00529     };
00530 
00531     hDllInst = hInst;
00532 
00533     atWindowTheme        = GlobalAddAtomW(szWindowTheme);
00534     atSubAppName         = GlobalAddAtomW(szSubAppName);
00535     atSubIdList          = GlobalAddAtomW(szSubIdList);
00536     atDialogThemeEnabled = GlobalAddAtomW(szDialogThemeEnabled);
00537     atWndContrext        = GlobalAddAtomW(L"ux_WndContext");
00538 }
00539 
00540 /***********************************************************************
00541  *      IsAppThemed                                         (UXTHEME.@)
00542  */
00543 BOOL WINAPI IsAppThemed(void)
00544 {
00545     return IsThemeActive();
00546 }
00547 
00548 /***********************************************************************
00549  *      IsThemeActive                                       (UXTHEME.@)
00550  */
00551 BOOL WINAPI IsThemeActive(void)
00552 {
00553     TRACE("\n");
00554     SetLastError(ERROR_SUCCESS);
00555     return bThemeActive;
00556 }
00557 
00558 /***********************************************************************
00559  *      EnableTheming                                       (UXTHEME.@)
00560  *
00561  * NOTES
00562  * This is a global and persistent change
00563  */
00564 HRESULT WINAPI EnableTheming(BOOL fEnable)
00565 {
00566     HKEY hKey;
00567     WCHAR szEnabled[] = {'0','\0'};
00568 
00569     TRACE("(%d)\n", fEnable);
00570 
00571     if(fEnable != bThemeActive) {
00572         if(fEnable) 
00573             UXTHEME_BackupSystemMetrics();
00574         else
00575             UXTHEME_RestoreSystemMetrics();
00576         UXTHEME_SaveSystemMetrics ();
00577         bThemeActive = fEnable;
00578         if(bThemeActive) szEnabled[0] = '1';
00579         if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
00580             RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (LPBYTE)szEnabled, sizeof(WCHAR));
00581             RegCloseKey(hKey);
00582         }
00583     UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED);
00584     }
00585     return S_OK;
00586 }
00587 
00588 /***********************************************************************
00589  *      UXTHEME_SetWindowProperty
00590  *
00591  * I'm using atoms as there may be large numbers of duplicated strings
00592  * and they do the work of keeping memory down as a cause of that quite nicely
00593  */
00594 static HRESULT UXTHEME_SetWindowProperty(HWND hwnd, ATOM aProp, LPCWSTR pszValue)
00595 {
00596     ATOM oldValue = (ATOM)(size_t)RemovePropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp));
00597     if(oldValue)
00598         DeleteAtom(oldValue);
00599     if(pszValue) {
00600         ATOM atValue = AddAtomW(pszValue);
00601         if(!atValue
00602            || !SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp), (LPWSTR)MAKEINTATOM(atValue))) {
00603             HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
00604             if(atValue) DeleteAtom(atValue);
00605             return hr;
00606         }
00607     }
00608     return S_OK;
00609 }
00610 
00611 static LPWSTR UXTHEME_GetWindowProperty(HWND hwnd, ATOM aProp, LPWSTR pszBuffer, int dwLen)
00612 {
00613     ATOM atValue = (ATOM)(size_t)GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp));
00614     if(atValue) {
00615         if(GetAtomNameW(atValue, pszBuffer, dwLen))
00616             return pszBuffer;
00617         TRACE("property defined, but unable to get value\n");
00618     }
00619     return NULL;
00620 }
00621 
00622 /***********************************************************************
00623  *      OpenThemeDataEx                                     (UXTHEME.61)
00624  */
00625 HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags)
00626 {
00627     WCHAR szAppBuff[256];
00628     WCHAR szClassBuff[256];
00629     LPCWSTR pszAppName;
00630     LPCWSTR pszUseClassList;
00631     HTHEME hTheme = NULL;
00632     TRACE("(%p,%s)\n", hwnd, debugstr_w(pszClassList));
00633     
00634     if(!pszClassList)
00635     {
00636         SetLastError(E_POINTER);
00637         return NULL;
00638     }
00639 
00640     if(flags)
00641         FIXME("unhandled flags: %x\n", flags);
00642 
00643     if(bThemeActive)
00644     {
00645         pszAppName = UXTHEME_GetWindowProperty(hwnd, atSubAppName, szAppBuff, sizeof(szAppBuff)/sizeof(szAppBuff[0]));
00646         /* If SetWindowTheme was used on the window, that overrides the class list passed to this function */
00647         pszUseClassList = UXTHEME_GetWindowProperty(hwnd, atSubIdList, szClassBuff, sizeof(szClassBuff)/sizeof(szClassBuff[0]));
00648         if(!pszUseClassList)
00649             pszUseClassList = pszClassList;
00650 
00651         if (pszUseClassList)
00652             hTheme = MSSTYLES_OpenThemeClass(pszAppName, pszUseClassList);
00653     }
00654     if(IsWindow(hwnd))
00655         SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme);
00656     TRACE(" = %p\n", hTheme);
00657     return hTheme;
00658 }
00659 
00660 /***********************************************************************
00661  *      OpenThemeData                                       (UXTHEME.@)
00662  */
00663 HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist)
00664 {
00665     return OpenThemeDataEx(hwnd, classlist, 0);
00666 }
00667 
00668 /***********************************************************************
00669  *      GetWindowTheme                                      (UXTHEME.@)
00670  *
00671  * Retrieve the last theme opened for a window.
00672  *
00673  * PARAMS
00674  *  hwnd  [I] window to retrieve the theme for
00675  *
00676  * RETURNS
00677  *  The most recent theme.
00678  */
00679 HTHEME WINAPI GetWindowTheme(HWND hwnd)
00680 {
00681     TRACE("(%p)\n", hwnd);
00682     if(!IsWindow(hwnd))
00683         SetLastError(E_HANDLE);
00684 
00685     return GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme));
00686 }
00687 
00688 /***********************************************************************
00689  *      SetWindowTheme                                      (UXTHEME.@)
00690  *
00691  * Persistent through the life of the window, even after themes change
00692  */
00693 HRESULT WINAPI SetWindowTheme(HWND hwnd, LPCWSTR pszSubAppName,
00694                               LPCWSTR pszSubIdList)
00695 {
00696     HRESULT hr;
00697     TRACE("(%p,%s,%s)\n", hwnd, debugstr_w(pszSubAppName),
00698         debugstr_w(pszSubIdList));
00699     
00700     if(!IsWindow(hwnd))
00701         return E_HANDLE;
00702 
00703     hr = UXTHEME_SetWindowProperty(hwnd, atSubAppName, pszSubAppName);
00704     if(SUCCEEDED(hr))
00705         hr = UXTHEME_SetWindowProperty(hwnd, atSubIdList, pszSubIdList);
00706     if(SUCCEEDED(hr))
00707     UXTHEME_broadcast_msg (hwnd, WM_THEMECHANGED);
00708     return hr;
00709 }
00710 
00711 /***********************************************************************
00712  *      GetCurrentThemeName                                 (UXTHEME.@)
00713  */
00714 HRESULT WINAPI GetCurrentThemeName(LPWSTR pszThemeFileName, int dwMaxNameChars,
00715                                    LPWSTR pszColorBuff, int cchMaxColorChars,
00716                                    LPWSTR pszSizeBuff, int cchMaxSizeChars)
00717 {
00718     if(!bThemeActive)
00719         return E_PROP_ID_UNSUPPORTED;
00720     if(pszThemeFileName) lstrcpynW(pszThemeFileName, szCurrentTheme, dwMaxNameChars);
00721     if(pszColorBuff) lstrcpynW(pszColorBuff, szCurrentColor, cchMaxColorChars);
00722     if(pszSizeBuff) lstrcpynW(pszSizeBuff, szCurrentSize, cchMaxSizeChars);
00723     return S_OK;
00724 }
00725 
00726 /***********************************************************************
00727  *      GetThemeAppProperties                               (UXTHEME.@)
00728  */
00729 DWORD WINAPI GetThemeAppProperties(void)
00730 {
00731     return dwThemeAppProperties;
00732 }
00733 
00734 /***********************************************************************
00735  *      SetThemeAppProperties                               (UXTHEME.@)
00736  */
00737 void WINAPI SetThemeAppProperties(DWORD dwFlags)
00738 {
00739     TRACE("(0x%08x)\n", dwFlags);
00740     dwThemeAppProperties = dwFlags;
00741 }
00742 
00743 /***********************************************************************
00744  *      CloseThemeData                                      (UXTHEME.@)
00745  */
00746 HRESULT WINAPI CloseThemeData(HTHEME hTheme)
00747 {
00748     TRACE("(%p)\n", hTheme);
00749     if(!hTheme)
00750         return E_HANDLE;
00751     return MSSTYLES_CloseThemeClass(hTheme);
00752 }
00753 
00754 /***********************************************************************
00755  *      HitTestThemeBackground                              (UXTHEME.@)
00756  */
00757 HRESULT WINAPI HitTestThemeBackground(HTHEME hTheme, HDC hdc, int iPartId,
00758                                      int iStateId, DWORD dwOptions,
00759                                      const RECT *pRect, HRGN hrgn,
00760                                      POINT ptTest, WORD *pwHitTestCode)
00761 {
00762     FIXME("%d %d 0x%08x: stub\n", iPartId, iStateId, dwOptions);
00763     if(!hTheme)
00764         return E_HANDLE;
00765     return ERROR_CALL_NOT_IMPLEMENTED;
00766 }
00767 
00768 /***********************************************************************
00769  *      IsThemePartDefined                                  (UXTHEME.@)
00770  */
00771 BOOL WINAPI IsThemePartDefined(HTHEME hTheme, int iPartId, int iStateId)
00772 {
00773     TRACE("(%p,%d,%d)\n", hTheme, iPartId, iStateId);
00774     if(!hTheme) {
00775         SetLastError(E_HANDLE);
00776         return FALSE;
00777     }
00778     if(MSSTYLES_FindPartState(hTheme, iPartId, iStateId, NULL))
00779         return TRUE;
00780     return FALSE;
00781 }
00782 
00783 /***********************************************************************
00784  *      GetThemeDocumentationProperty                       (UXTHEME.@)
00785  *
00786  * Try and retrieve the documentation property from string resources
00787  * if that fails, get it from the [documentation] section of themes.ini
00788  */
00789 HRESULT WINAPI GetThemeDocumentationProperty(LPCWSTR pszThemeName,
00790                                              LPCWSTR pszPropertyName,
00791                                              LPWSTR pszValueBuff,
00792                                              int cchMaxValChars)
00793 {
00794     const WORD wDocToRes[] = {
00795         TMT_DISPLAYNAME,5000,
00796         TMT_TOOLTIP,5001,
00797         TMT_COMPANY,5002,
00798         TMT_AUTHOR,5003,
00799         TMT_COPYRIGHT,5004,
00800         TMT_URL,5005,
00801         TMT_VERSION,5006,
00802         TMT_DESCRIPTION,5007
00803     };
00804 
00805     PTHEME_FILE pt;
00806     HRESULT hr;
00807     unsigned int i;
00808     int iDocId;
00809     TRACE("(%s,%s,%p,%d)\n", debugstr_w(pszThemeName), debugstr_w(pszPropertyName),
00810           pszValueBuff, cchMaxValChars);
00811 
00812     hr = MSSTYLES_OpenThemeFile(pszThemeName, NULL, NULL, &pt);
00813     if(FAILED(hr)) return hr;
00814 
00815     /* Try to load from string resources */
00816     hr = E_PROP_ID_UNSUPPORTED;
00817     if(MSSTYLES_LookupProperty(pszPropertyName, NULL, &iDocId)) {
00818         for(i=0; i<sizeof(wDocToRes)/sizeof(wDocToRes[0]); i+=2) {
00819             if(wDocToRes[i] == iDocId) {
00820                 if(LoadStringW(pt->hTheme, wDocToRes[i+1], pszValueBuff, cchMaxValChars)) {
00821                     hr = S_OK;
00822                     break;
00823                 }
00824             }
00825         }
00826     }
00827     /* If loading from string resource failed, try getting it from the theme.ini */
00828     if(FAILED(hr)) {
00829         PUXINI_FILE uf = MSSTYLES_GetThemeIni(pt);
00830         if(UXINI_FindSection(uf, szIniDocumentation)) {
00831             LPCWSTR lpValue;
00832             DWORD dwLen;
00833             if(UXINI_FindValue(uf, pszPropertyName, &lpValue, &dwLen)) {
00834                 lstrcpynW(pszValueBuff, lpValue, min(dwLen+1,cchMaxValChars));
00835                 hr = S_OK;
00836             }
00837         }
00838         UXINI_CloseINI(uf);
00839     }
00840 
00841     MSSTYLES_CloseThemeFile(pt);
00842     return hr;
00843 }
00844 
00845 /**********************************************************************
00846  *      Undocumented functions
00847  */
00848 
00849 /**********************************************************************
00850  *      QueryThemeServices                                 (UXTHEME.1)
00851  *
00852  * RETURNS
00853  *     some kind of status flag
00854  */
00855 DWORD WINAPI QueryThemeServices(void)
00856 {
00857     FIXME("stub\n");
00858     return 3; /* This is what is returned under XP in most cases */
00859 }
00860 
00861 
00862 /**********************************************************************
00863  *      OpenThemeFile                                      (UXTHEME.2)
00864  *
00865  * Opens a theme file, which can be used to change the current theme, etc
00866  *
00867  * PARAMS
00868  *     pszThemeFileName    Path to a msstyles theme file
00869  *     pszColorName        Color defined in the theme, eg. NormalColor
00870  *     pszSizeName         Size defined in the theme, eg. NormalSize
00871  *     hThemeFile          Handle to theme file
00872  *
00873  * RETURNS
00874  *     Success: S_OK
00875  *     Failure: HRESULT error-code
00876  */
00877 HRESULT WINAPI OpenThemeFile(LPCWSTR pszThemeFileName, LPCWSTR pszColorName,
00878                              LPCWSTR pszSizeName, HTHEMEFILE *hThemeFile,
00879                              DWORD unknown)
00880 {
00881     TRACE("(%s,%s,%s,%p,%d)\n", debugstr_w(pszThemeFileName),
00882           debugstr_w(pszColorName), debugstr_w(pszSizeName),
00883           hThemeFile, unknown);
00884     return MSSTYLES_OpenThemeFile(pszThemeFileName, pszColorName, pszSizeName, (PTHEME_FILE*)hThemeFile);
00885 }
00886 
00887 /**********************************************************************
00888  *      CloseThemeFile                                     (UXTHEME.3)
00889  *
00890  * Releases theme file handle returned by OpenThemeFile
00891  *
00892  * PARAMS
00893  *     hThemeFile           Handle to theme file
00894  *
00895  * RETURNS
00896  *     Success: S_OK
00897  *     Failure: HRESULT error-code
00898  */
00899 HRESULT WINAPI CloseThemeFile(HTHEMEFILE hThemeFile)
00900 {
00901     TRACE("(%p)\n", hThemeFile);
00902     MSSTYLES_CloseThemeFile(hThemeFile);
00903     return S_OK;
00904 }
00905 
00906 /**********************************************************************
00907  *      ApplyTheme                                         (UXTHEME.4)
00908  *
00909  * Set a theme file to be the currently active theme
00910  *
00911  * PARAMS
00912  *     hThemeFile           Handle to theme file
00913  *     unknown              See notes
00914  *     hWnd                 Window requesting the theme change
00915  *
00916  * RETURNS
00917  *     Success: S_OK
00918  *     Failure: HRESULT error-code
00919  *
00920  * NOTES
00921  * I'm not sure what the second parameter is (the datatype is likely wrong), other then this:
00922  * Under XP if I pass
00923  * char b[] = "";
00924  *   the theme is applied with the screen redrawing really badly (flickers)
00925  * char b[] = "\0"; where \0 can be one or more of any character, makes no difference
00926  *   the theme is applied smoothly (screen does not flicker)
00927  * char *b = "\0" or NULL; where \0 can be zero or more of any character, makes no difference
00928  *   the function fails returning invalid parameter... very strange
00929  */
00930 HRESULT WINAPI ApplyTheme(HTHEMEFILE hThemeFile, char *unknown, HWND hWnd)
00931 {
00932     HRESULT hr;
00933     TRACE("(%p,%s,%p)\n", hThemeFile, unknown, hWnd);
00934     hr = UXTHEME_SetActiveTheme(hThemeFile);
00935     UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED);
00936     return hr;
00937 }
00938 
00939 /**********************************************************************
00940  *      GetThemeDefaults                                   (UXTHEME.7)
00941  *
00942  * Get the default color & size for a theme
00943  *
00944  * PARAMS
00945  *     pszThemeFileName    Path to a msstyles theme file
00946  *     pszColorName        Buffer to receive the default color name
00947  *     dwColorNameLen      Length, in characters, of color name buffer
00948  *     pszSizeName         Buffer to receive the default size name
00949  *     dwSizeNameLen       Length, in characters, of size name buffer
00950  *
00951  * RETURNS
00952  *     Success: S_OK
00953  *     Failure: HRESULT error-code
00954  */
00955 HRESULT WINAPI GetThemeDefaults(LPCWSTR pszThemeFileName, LPWSTR pszColorName,
00956                                 DWORD dwColorNameLen, LPWSTR pszSizeName,
00957                                 DWORD dwSizeNameLen)
00958 {
00959     PTHEME_FILE pt;
00960     HRESULT hr;
00961     TRACE("(%s,%p,%d,%p,%d)\n", debugstr_w(pszThemeFileName),
00962           pszColorName, dwColorNameLen,
00963           pszSizeName, dwSizeNameLen);
00964 
00965     hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, NULL, &pt);
00966     if(FAILED(hr)) return hr;
00967 
00968     lstrcpynW(pszColorName, pt->pszSelectedColor, dwColorNameLen);
00969     lstrcpynW(pszSizeName, pt->pszSelectedSize, dwSizeNameLen);
00970 
00971     MSSTYLES_CloseThemeFile(pt);
00972     return S_OK;
00973 }
00974 
00975 /**********************************************************************
00976  *      EnumThemes                                         (UXTHEME.8)
00977  *
00978  * Enumerate available themes, calls specified EnumThemeProc for each
00979  * theme found. Passes lpData through to callback function.
00980  *
00981  * PARAMS
00982  *     pszThemePath        Path containing themes
00983  *     callback            Called for each theme found in path
00984  *     lpData              Passed through to callback
00985  *
00986  * RETURNS
00987  *     Success: S_OK
00988  *     Failure: HRESULT error-code
00989  */
00990 HRESULT WINAPI EnumThemes(LPCWSTR pszThemePath, ENUMTHEMEPROC callback,
00991                           LPVOID lpData)
00992 {
00993     WCHAR szDir[MAX_PATH];
00994     WCHAR szPath[MAX_PATH];
00995     static const WCHAR szStar[] = {'*','.','*','\0'};
00996     static const WCHAR szFormat[] = {'%','s','%','s','\\','%','s','.','m','s','s','t','y','l','e','s','\0'};
00997     static const WCHAR szDisplayName[] = {'d','i','s','p','l','a','y','n','a','m','e','\0'};
00998     static const WCHAR szTooltip[] = {'t','o','o','l','t','i','p','\0'};
00999     WCHAR szName[60];
01000     WCHAR szTip[60];
01001     HANDLE hFind;
01002     WIN32_FIND_DATAW wfd;
01003     HRESULT hr;
01004     size_t pathLen;
01005 
01006     TRACE("(%s,%p,%p)\n", debugstr_w(pszThemePath), callback, lpData);
01007 
01008     if(!pszThemePath || !callback)
01009         return E_POINTER;
01010 
01011     lstrcpyW(szDir, pszThemePath);
01012     pathLen = lstrlenW (szDir);
01013     if ((pathLen > 0) && (pathLen < MAX_PATH-1) && (szDir[pathLen - 1] != '\\'))
01014     {
01015         szDir[pathLen] = '\\';
01016         szDir[pathLen+1] = 0;
01017     }
01018 
01019     lstrcpyW(szPath, szDir);
01020     lstrcatW(szPath, szStar);
01021     TRACE("searching %s\n", debugstr_w(szPath));
01022 
01023     hFind = FindFirstFileW(szPath, &wfd);
01024     if(hFind != INVALID_HANDLE_VALUE) {
01025         do {
01026             if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
01027                && !(wfd.cFileName[0] == '.' && ((wfd.cFileName[1] == '.' && wfd.cFileName[2] == 0) || wfd.cFileName[1] == 0))) {
01028                 wsprintfW(szPath, szFormat, szDir, wfd.cFileName, wfd.cFileName);
01029 
01030                 hr = GetThemeDocumentationProperty(szPath, szDisplayName, szName, sizeof(szName)/sizeof(szName[0]));
01031                 if(SUCCEEDED(hr))
01032                     hr = GetThemeDocumentationProperty(szPath, szTooltip, szTip, sizeof(szTip)/sizeof(szTip[0]));
01033                 if(SUCCEEDED(hr)) {
01034                     TRACE("callback(%s,%s,%s,%p)\n", debugstr_w(szPath), debugstr_w(szName), debugstr_w(szTip), lpData);
01035                     if(!callback(NULL, szPath, szName, szTip, NULL, lpData)) {
01036                         TRACE("callback ended enum\n");
01037                         break;
01038                     }
01039                 }
01040             }
01041         } while(FindNextFileW(hFind, &wfd));
01042         FindClose(hFind);
01043     }
01044     return S_OK;
01045 }
01046 
01047 
01048 /**********************************************************************
01049  *      EnumThemeColors                                    (UXTHEME.9)
01050  *
01051  * Enumerate theme colors available with a particular size
01052  *
01053  * PARAMS
01054  *     pszThemeFileName    Path to a msstyles theme file
01055  *     pszSizeName         Theme size to enumerate available colors
01056  *                         If NULL the default theme size is used
01057  *     dwColorNum          Color index to retrieve, increment from 0
01058  *     pszColorNames       Output color names
01059  *
01060  * RETURNS
01061  *     S_OK on success
01062  *     E_PROP_ID_UNSUPPORTED when dwColorName does not refer to a color
01063  *          or when pszSizeName does not refer to a valid size
01064  *
01065  * NOTES
01066  * XP fails with E_POINTER when pszColorNames points to a buffer smaller than 
01067  * sizeof(THEMENAMES).
01068  *
01069  * Not very efficient that I'm opening & validating the theme every call, but
01070  * this is undocumented and almost never called..
01071  * (and this is how windows works too)
01072  */
01073 HRESULT WINAPI EnumThemeColors(LPWSTR pszThemeFileName, LPWSTR pszSizeName,
01074                                DWORD dwColorNum, PTHEMENAMES pszColorNames)
01075 {
01076     PTHEME_FILE pt;
01077     HRESULT hr;
01078     LPWSTR tmp;
01079     UINT resourceId = dwColorNum + 1000;
01080     TRACE("(%s,%s,%d)\n", debugstr_w(pszThemeFileName),
01081           debugstr_w(pszSizeName), dwColorNum);
01082 
01083     hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, pszSizeName, &pt);
01084     if(FAILED(hr)) return hr;
01085 
01086     tmp = pt->pszAvailColors;
01087     while(dwColorNum && *tmp) {
01088         dwColorNum--;
01089         tmp += lstrlenW(tmp)+1;
01090     }
01091     if(!dwColorNum && *tmp) {
01092         TRACE("%s\n", debugstr_w(tmp));
01093         lstrcpyW(pszColorNames->szName, tmp);
01094         LoadStringW (pt->hTheme, resourceId,
01095             pszColorNames->szDisplayName,
01096             sizeof (pszColorNames->szDisplayName) / sizeof (WCHAR));
01097         LoadStringW (pt->hTheme, resourceId+1000,
01098             pszColorNames->szTooltip,
01099             sizeof (pszColorNames->szTooltip) / sizeof (WCHAR));
01100     }
01101     else
01102         hr = E_PROP_ID_UNSUPPORTED;
01103 
01104     MSSTYLES_CloseThemeFile(pt);
01105     return hr;
01106 }
01107 
01108 /**********************************************************************
01109  *      EnumThemeSizes                                     (UXTHEME.10)
01110  *
01111  * Enumerate theme colors available with a particular size
01112  *
01113  * PARAMS
01114  *     pszThemeFileName    Path to a msstyles theme file
01115  *     pszColorName        Theme color to enumerate available sizes
01116  *                         If NULL the default theme color is used
01117  *     dwSizeNum           Size index to retrieve, increment from 0
01118  *     pszSizeNames        Output size names
01119  *
01120  * RETURNS
01121  *     S_OK on success
01122  *     E_PROP_ID_UNSUPPORTED when dwSizeName does not refer to a size
01123  *          or when pszColorName does not refer to a valid color
01124  *
01125  * NOTES
01126  * XP fails with E_POINTER when pszSizeNames points to a buffer smaller than 
01127  * sizeof(THEMENAMES).
01128  *
01129  * Not very efficient that I'm opening & validating the theme every call, but
01130  * this is undocumented and almost never called..
01131  * (and this is how windows works too)
01132  */
01133 HRESULT WINAPI EnumThemeSizes(LPWSTR pszThemeFileName, LPWSTR pszColorName,
01134                               DWORD dwSizeNum, PTHEMENAMES pszSizeNames)
01135 {
01136     PTHEME_FILE pt;
01137     HRESULT hr;
01138     LPWSTR tmp;
01139     UINT resourceId = dwSizeNum + 3000;
01140     TRACE("(%s,%s,%d)\n", debugstr_w(pszThemeFileName),
01141           debugstr_w(pszColorName), dwSizeNum);
01142 
01143     hr = MSSTYLES_OpenThemeFile(pszThemeFileName, pszColorName, NULL, &pt);
01144     if(FAILED(hr)) return hr;
01145 
01146     tmp = pt->pszAvailSizes;
01147     while(dwSizeNum && *tmp) {
01148         dwSizeNum--;
01149         tmp += lstrlenW(tmp)+1;
01150     }
01151     if(!dwSizeNum && *tmp) {
01152         TRACE("%s\n", debugstr_w(tmp));
01153         lstrcpyW(pszSizeNames->szName, tmp);
01154         LoadStringW (pt->hTheme, resourceId,
01155             pszSizeNames->szDisplayName,
01156             sizeof (pszSizeNames->szDisplayName) / sizeof (WCHAR));
01157         LoadStringW (pt->hTheme, resourceId+1000,
01158             pszSizeNames->szTooltip,
01159             sizeof (pszSizeNames->szTooltip) / sizeof (WCHAR));
01160     }
01161     else
01162         hr = E_PROP_ID_UNSUPPORTED;
01163 
01164     MSSTYLES_CloseThemeFile(pt);
01165     return hr;
01166 }
01167 
01168 /**********************************************************************
01169  *      ParseThemeIniFile                                  (UXTHEME.11)
01170  *
01171  * Enumerate data in a theme INI file.
01172  *
01173  * PARAMS
01174  *     pszIniFileName      Path to a theme ini file
01175  *     pszUnknown          Cannot be NULL, L"" is valid
01176  *     callback            Called for each found entry
01177  *     lpData              Passed through to callback
01178  *
01179  * RETURNS
01180  *     S_OK on success
01181  *     0x800706488 (Unknown property) when enumeration is canceled from callback
01182  *
01183  * NOTES
01184  * When pszUnknown is NULL the callback is never called, the value does not seem to serve
01185  * any other purpose
01186  */
01187 HRESULT WINAPI ParseThemeIniFile(LPCWSTR pszIniFileName, LPWSTR pszUnknown,
01188                                  PARSETHEMEINIFILEPROC callback, LPVOID lpData)
01189 {
01190     FIXME("%s %s: stub\n", debugstr_w(pszIniFileName), debugstr_w(pszUnknown));
01191     return ERROR_CALL_NOT_IMPLEMENTED;
01192 }
01193 
01194 /**********************************************************************
01195  *      CheckThemeSignature                                (UXTHEME.29)
01196  *
01197  * Validates the signature of a theme file
01198  *
01199  * PARAMS
01200  *     pszIniFileName      Path to a theme file
01201  *
01202  * RETURNS
01203  *     Success: S_OK
01204  *     Failure: HRESULT error-code
01205  */
01206 HRESULT WINAPI CheckThemeSignature(LPCWSTR pszThemeFileName)
01207 {
01208     PTHEME_FILE pt;
01209     HRESULT hr;
01210     TRACE("(%s)\n", debugstr_w(pszThemeFileName));
01211     hr = MSSTYLES_OpenThemeFile(pszThemeFileName, NULL, NULL, &pt);
01212     if(FAILED(hr))
01213         return hr;
01214     MSSTYLES_CloseThemeFile(pt);
01215     return S_OK;
01216 }

Generated on Sun May 27 2012 04:16:35 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.