Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensystem.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
1.7.6.1
|