Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentheme.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Display Control Panel 00004 * FILE: dll/cpl/desk/theme.c 00005 * PURPOSE: Handling themes 00006 * 00007 * PROGRAMMERS: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 00008 */ 00009 00010 #include "desk.h" 00011 00012 static BOOL g_PresetLoaded = FALSE; 00013 INT g_TemplateCount = 0; 00014 00015 static INT g_ColorList[NUM_COLORS]; 00016 00017 static const TCHAR g_CPColors[] = TEXT("Control Panel\\Colors"); 00018 static const TCHAR g_CPANewSchemes[] = TEXT("Control Panel\\Appearance\\New Schemes"); 00019 static const TCHAR g_SelectedStyle[] = TEXT("SelectedStyle"); 00020 00021 /******************************************************************************/ 00022 00023 SCHEME_PRESET g_ColorSchemes[MAX_TEMPLATES]; 00024 00025 /* This is the list of names for the colors stored in the registry */ 00026 static const TCHAR *g_RegColorNames[NUM_COLORS] = 00027 {TEXT("Scrollbar"), /* 00 = COLOR_SCROLLBAR */ 00028 TEXT("Background"), /* 01 = COLOR_DESKTOP */ 00029 TEXT("ActiveTitle"), /* 02 = COLOR_ACTIVECAPTION */ 00030 TEXT("InactiveTitle"), /* 03 = COLOR_INACTIVECAPTION */ 00031 TEXT("Menu"), /* 04 = COLOR_MENU */ 00032 TEXT("Window"), /* 05 = COLOR_WINDOW */ 00033 TEXT("WindowFrame"), /* 06 = COLOR_WINDOWFRAME */ 00034 TEXT("MenuText"), /* 07 = COLOR_MENUTEXT */ 00035 TEXT("WindowText"), /* 08 = COLOR_WINDOWTEXT */ 00036 TEXT("TitleText"), /* 09 = COLOR_CAPTIONTEXT */ 00037 TEXT("ActiveBorder"), /* 10 = COLOR_ACTIVEBORDER */ 00038 TEXT("InactiveBorder"), /* 11 = COLOR_INACTIVEBORDER */ 00039 TEXT("AppWorkSpace"), /* 12 = COLOR_APPWORKSPACE */ 00040 TEXT("Hilight"), /* 13 = COLOR_HIGHLIGHT */ 00041 TEXT("HilightText"), /* 14 = COLOR_HIGHLIGHTTEXT */ 00042 TEXT("ButtonFace"), /* 15 = COLOR_BTNFACE */ 00043 TEXT("ButtonShadow"), /* 16 = COLOR_BTNSHADOW */ 00044 TEXT("GrayText"), /* 17 = COLOR_GRAYTEXT */ 00045 TEXT("ButtonText"), /* 18 = COLOR_BTNTEXT */ 00046 TEXT("InactiveTitleText"), /* 19 = COLOR_INACTIVECAPTIONTEXT */ 00047 TEXT("ButtonHilight"), /* 20 = COLOR_BTNHIGHLIGHT */ 00048 TEXT("ButtonDkShadow"), /* 21 = COLOR_3DDKSHADOW */ 00049 TEXT("ButtonLight"), /* 22 = COLOR_3DLIGHT */ 00050 TEXT("InfoText"), /* 23 = COLOR_INFOTEXT */ 00051 TEXT("InfoWindow"), /* 24 = COLOR_INFOBK */ 00052 TEXT("ButtonAlternateFace"), /* 25 = COLOR_ALTERNATEBTNFACE */ 00053 TEXT("HotTrackingColor"), /* 26 = COLOR_HOTLIGHT */ 00054 TEXT("GradientActiveTitle"), /* 27 = COLOR_GRADIENTACTIVECAPTION */ 00055 TEXT("GradientInactiveTitle"), /* 28 = COLOR_GRADIENTINACTIVECAPTION */ 00056 TEXT("MenuHilight"), /* 29 = COLOR_MENUHILIGHT */ 00057 TEXT("MenuBar"), /* 30 = COLOR_MENUBAR */ 00058 }; 00059 00060 /* This is the list of used metrics and their numbers */ 00061 static const int g_SizeMetric[NUM_SIZES] = 00062 { 00063 SM_CXBORDER, /* 00: SIZE_BORDER_X */ 00064 SM_CYBORDER, /* 01: SIZE_BORDER_Y */ 00065 SM_CYSIZE, /* 02: SIZE_CAPTION_Y */ 00066 SM_CXICON, /* 03: SIZE_ICON_X */ 00067 SM_CYICON, /* 04: SIZE_ICON_Y */ 00068 SM_CXICONSPACING, /* 05: SIZE_ICON_SPC_X */ 00069 SM_CYICONSPACING, /* 06: SIZE_ICON_SPC_Y */ 00070 SM_CXMENUSIZE, /* 07: SIZE_MENU_SIZE_X */ 00071 SM_CYMENU, /* 08: SIZE_MENU_Y */ 00072 SM_CXVSCROLL, /* 09: SIZE_SCROLL_X */ 00073 SM_CYHSCROLL, /* 10: SIZE_SCROLL_Y */ 00074 SM_CYSMSIZE, /* 11: SIZE_SMCAPTION_Y */ 00075 SM_CXEDGE, /* 12: SIZE_EDGE_X */ 00076 SM_CYEDGE, /* 13: SIZE_EDGE_Y */ 00077 SM_CYSIZEFRAME, /* 14: SIZE_FRAME_Y */ 00078 SM_CXMENUCHECK, /* 15: SIZE_MENU_CHECK_X */ 00079 SM_CYMENUCHECK, /* 16: SIZE_MENU_CHECK_Y */ 00080 SM_CYMENUSIZE, /* 17: SIZE_MENU_SIZE_Y */ 00081 SM_CXSIZE, /* 18: SIZE_SIZE_X */ 00082 SM_CYSIZE /* 19: SIZE_SIZE_Y */ 00083 }; 00084 00085 /******************************************************************************/ 00086 00087 VOID LoadCurrentScheme(COLOR_SCHEME* scheme) 00088 { 00089 INT i; 00090 NONCLIENTMETRICS NonClientMetrics; 00091 00092 /* Load colors */ 00093 for (i = 0; i < NUM_COLORS; i++) 00094 { 00095 g_ColorList[i] = i; 00096 scheme->crColor[i] = (COLORREF)GetSysColor(i); 00097 } 00098 00099 /* Load sizes */ 00100 for (i = 0; i < NUM_SIZES; i++) 00101 { 00102 scheme->Size[i] = GetSystemMetrics(g_SizeMetric[i]); 00103 } 00104 00105 /* Load fonts */ 00106 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS); 00107 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0); 00108 scheme->lfFont[FONT_CAPTION] = NonClientMetrics.lfCaptionFont; 00109 scheme->lfFont[FONT_SMCAPTION] = NonClientMetrics.lfSmCaptionFont; 00110 scheme->lfFont[FONT_MENU] = NonClientMetrics.lfMenuFont; 00111 scheme->lfFont[FONT_INFO] = NonClientMetrics.lfStatusFont; 00112 scheme->lfFont[FONT_DIALOG] = NonClientMetrics.lfMessageFont; 00113 SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &scheme->lfFont[FONT_ICON], 0); 00114 00115 /* Effects */ 00116 /* "Use the following transition effect for menus and tooltips" */ 00117 SystemParametersInfo(SPI_GETMENUANIMATION, sizeof(BOOL), &scheme->Effects.bMenuAnimation, 0); 00118 SystemParametersInfo(SPI_GETMENUFADE, sizeof(BOOL), &scheme->Effects.bMenuFade, 0); 00119 /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings 00120 * Just keep them in sync for now: 00121 */ 00122 scheme->Effects.bTooltipAnimation = scheme->Effects.bMenuAnimation; 00123 scheme->Effects.bTooltipFade = scheme->Effects.bMenuFade; 00124 00125 /* Show content of windows during dragging */ 00126 SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &scheme->Effects.bDragFullWindows, 0); 00127 00128 /* "Hide underlined letters for keyboard navigation until I press the Alt key" */ 00129 SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &scheme->Effects.bKeyboardCues, 0); 00130 } 00131 00132 BOOL LoadSchemeFromReg(COLOR_SCHEME* scheme, INT SchemeId) 00133 { 00134 INT i; 00135 TCHAR strSelectedStyle[4]; 00136 TCHAR strSizeName[20] = TEXT("Sizes\\0"); 00137 TCHAR strValueName[10]; 00138 HKEY hkNewSchemes, hkScheme, hkSize; 00139 DWORD dwType, dwLength; 00140 UINT64 iSize; 00141 BOOL Ret = FALSE; 00142 00143 if (!g_PresetLoaded) 00144 LoadSchemePresetEntries(strSelectedStyle); 00145 00146 if (SchemeId == -1) 00147 return FALSE; 00148 00149 if (RegOpenKeyEx(HKEY_CURRENT_USER, g_CPANewSchemes, 0, KEY_READ, &hkNewSchemes) == ERROR_SUCCESS) 00150 { 00151 if (RegOpenKeyEx(hkNewSchemes, g_ColorSchemes[SchemeId].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS) 00152 { 00153 lstrcpyn(&strSizeName[6], g_ColorSchemes[SchemeId].strSizeName, 3); 00154 if (RegOpenKeyEx(hkScheme, strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS) 00155 { 00156 Ret = TRUE; 00157 00158 dwLength = sizeof(DWORD); 00159 if (RegQueryValueEx(hkSize, TEXT("FlatMenus"), NULL, &dwType, (LPBYTE)&scheme->bFlatMenus, &dwLength) != ERROR_SUCCESS || 00160 dwType != REG_DWORD) 00161 { 00162 /* Failed to read registry value */ 00163 scheme->bFlatMenus = FALSE; 00164 } 00165 00166 for (i = 0; i < NUM_COLORS; i++) 00167 { 00168 wsprintf(strValueName, TEXT("Color #%d"), i); 00169 dwLength = sizeof(COLORREF); 00170 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&scheme->crColor[i], &dwLength) != ERROR_SUCCESS || 00171 dwType != REG_DWORD) 00172 { 00173 /* Failed to read registry value, initialize with current setting for now */ 00174 scheme->crColor[i] = GetSysColor(i); 00175 } 00176 } 00177 00178 for (i = 0; i < NUM_FONTS; i++) 00179 { 00180 wsprintf(strValueName, TEXT("Font #%d"), i); 00181 dwLength = sizeof(LOGFONT); 00182 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&scheme->lfFont[i], &dwLength) != ERROR_SUCCESS || 00183 dwType != REG_BINARY || dwLength != sizeof(LOGFONT)) 00184 { 00185 /* Failed to read registry value */ 00186 Ret = FALSE; 00187 } 00188 } 00189 00190 for (i = 0; i < NUM_SIZES; i++) 00191 { 00192 wsprintf(strValueName, TEXT("Size #%d"), i); 00193 dwLength = sizeof(UINT64); 00194 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&iSize, &dwLength) != ERROR_SUCCESS || 00195 dwType != REG_QWORD || dwLength != sizeof(UINT64)) 00196 { 00197 /* Failed to read registry value, initialize with current setting for now */ 00198 scheme->Size[i] = GetSystemMetrics(g_SizeMetric[i]); 00199 } 00200 else 00201 scheme->Size[i] = (INT)iSize; 00202 } 00203 RegCloseKey(hkSize); 00204 } 00205 RegCloseKey(hkScheme); 00206 } 00207 RegCloseKey(hkNewSchemes); 00208 } 00209 00210 return Ret; 00211 } 00212 00213 VOID ApplyScheme(COLOR_SCHEME* scheme, INT SchemeId) 00214 { 00215 INT i, Result; 00216 HKEY hKey; 00217 TCHAR clText[16]; 00218 NONCLIENTMETRICS NonClientMetrics; 00219 ICONMETRICS IconMetrics; 00220 00221 /* Apply Colors from global variable */ 00222 SetSysColors(NUM_COLORS, g_ColorList, scheme->crColor); 00223 00224 /* Save colors to registry */ 00225 Result = RegCreateKeyEx(HKEY_CURRENT_USER, g_CPColors, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL); 00226 if (Result == ERROR_SUCCESS) 00227 { 00228 for (i = 0; i < NUM_COLORS; i++) 00229 { 00230 DWORD red = GetRValue(scheme->crColor[i]); 00231 DWORD green = GetGValue(scheme->crColor[i]); 00232 DWORD blue = GetBValue(scheme->crColor[i]); 00233 wsprintf(clText, TEXT("%d %d %d"), red, green, blue); 00234 RegSetValueEx(hKey, g_RegColorNames[i], 0, REG_SZ, (BYTE *)clText, (lstrlen(clText) + 1) * sizeof(TCHAR)); 00235 } 00236 RegCloseKey(hKey); 00237 } 00238 00239 /* Apply non client metrics */ 00240 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS); 00241 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0); 00242 NonClientMetrics.lfCaptionFont = scheme->lfFont[FONT_CAPTION]; 00243 NonClientMetrics.lfSmCaptionFont = scheme->lfFont[FONT_SMCAPTION]; 00244 NonClientMetrics.lfMenuFont = scheme->lfFont[FONT_MENU]; 00245 NonClientMetrics.lfStatusFont = scheme->lfFont[FONT_INFO]; 00246 NonClientMetrics.lfMessageFont = scheme->lfFont[FONT_DIALOG]; 00247 NonClientMetrics.iBorderWidth = scheme->Size[SIZE_BORDER_X]; 00248 NonClientMetrics.iScrollWidth = scheme->Size[SIZE_SCROLL_X]; 00249 NonClientMetrics.iScrollHeight = scheme->Size[SIZE_SCROLL_Y]; 00250 NonClientMetrics.iCaptionWidth = scheme->Size[SIZE_CAPTION_Y]; 00251 NonClientMetrics.iCaptionHeight = scheme->Size[SIZE_CAPTION_Y]; 00252 NonClientMetrics.iSmCaptionWidth = scheme->Size[SIZE_SMCAPTION_Y]; 00253 NonClientMetrics.iSmCaptionHeight = scheme->Size[SIZE_SMCAPTION_Y]; 00254 NonClientMetrics.iMenuWidth = scheme->Size[SIZE_MENU_SIZE_X]; 00255 NonClientMetrics.iMenuHeight = scheme->Size[SIZE_MENU_Y]; 00256 SystemParametersInfo(SPI_SETNONCLIENTMETRICS, 00257 sizeof(NONCLIENTMETRICS), 00258 &NonClientMetrics, 00259 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); 00260 00261 /* Apply icon metrics */ 00262 IconMetrics.cbSize = sizeof(ICONMETRICS); 00263 SystemParametersInfo(SPI_GETICONMETRICS, sizeof(ICONMETRICS), &IconMetrics, 0); 00264 IconMetrics.iHorzSpacing = scheme->Size[SIZE_ICON_SPC_X]; 00265 IconMetrics.iVertSpacing = scheme->Size[SIZE_ICON_SPC_Y]; 00266 IconMetrics.lfFont = scheme->lfFont[FONT_ICON]; 00267 SystemParametersInfo(SPI_SETICONMETRICS, 00268 sizeof(ICONMETRICS), 00269 &IconMetrics, 00270 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); 00271 00272 /* Effects, save only when needed: */ 00273 /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings 00274 * Just keep them in sync for now. 00275 */ 00276 scheme->Effects.bTooltipAnimation = scheme->Effects.bMenuAnimation; 00277 scheme->Effects.bTooltipFade = scheme->Effects.bMenuFade; 00278 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, scheme->Effects.bDragFullWindows, (PVOID)&scheme->Effects.bDragFullWindows, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 00279 SystemParametersInfo(SPI_SETKEYBOARDCUES, 0, IntToPtr(scheme->Effects.bKeyboardCues), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 00280 //SystemParametersInfo(SPI_SETACTIVEWINDOWTRACKING, 0, (PVOID)&scheme->Effects.bActiveWindowTracking, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00281 //SystemParametersInfo(SPI_SETMENUANIMATION, 0, (PVOID)&scheme->Effects.bMenuAnimation, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00282 //SystemParametersInfo(SPI_SETCOMBOBOXANIMATION, 0, (PVOID)&scheme->Effects.bComboBoxAnimation, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00283 //SystemParametersInfo(SPI_SETLISTBOXSMOOTHSCROLLING, 0, (PVOID)&scheme->Effects.bListBoxSmoothScrolling, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00284 //SystemParametersInfo(SPI_SETGRADIENTCAPTIONS, 0, (PVOID)&scheme->Effects.bGradientCaptions, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00285 //SystemParametersInfo(SPI_SETACTIVEWNDTRKZORDER, 0, (PVOID)&scheme->Effects.bActiveWndTrkZorder, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00286 //SystemParametersInfo(SPI_SETHOTTRACKING, 0, (PVOID)&scheme->Effects.bHotTracking, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00287 SystemParametersInfo(SPI_SETMENUFADE, 0, (PVOID)&scheme->Effects.bMenuFade, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00288 //SystemParametersInfo(SPI_SETSELECTIONFADE, 0, (PVOID)&scheme->Effects.bSelectionFade, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00289 SystemParametersInfo(SPI_SETTOOLTIPANIMATION, 0, (PVOID)&scheme->Effects.bTooltipAnimation, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00290 SystemParametersInfo(SPI_SETTOOLTIPFADE, 0, (PVOID)&scheme->Effects.bTooltipFade, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00291 //SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)&scheme->Effects.bCursorShadow, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00292 //SystemParametersInfo(SPI_SETUIEFFECTS, 0, (PVOID)&scheme->Effects.bUiEffects, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 00293 00294 /* Save SchemeId */ 00295 Result = RegOpenKeyEx(HKEY_CURRENT_USER, g_CPANewSchemes, 0, KEY_ALL_ACCESS, &hKey); 00296 if (Result == ERROR_SUCCESS) 00297 { 00298 if (SchemeId == -1) 00299 clText[0] = TEXT('\0'); 00300 else 00301 lstrcpy(clText, g_ColorSchemes[SchemeId].strKeyName); 00302 RegSetValueEx(hKey, g_SelectedStyle, 0, REG_SZ, (BYTE *)clText, (lstrlen(clText) + 1) * sizeof(TCHAR)); 00303 RegCloseKey(hKey); 00304 } 00305 } 00306 00307 BOOL SaveScheme(COLOR_SCHEME* scheme, LPCTSTR strLegacyName) 00308 { 00309 /* FIXME: Implement */ 00310 return FALSE; 00311 } 00312 00313 INT LoadSchemePresetEntries(LPTSTR pszSelectedStyle) 00314 { 00315 HKEY hkNewSchemes, hkScheme, hkSizes, hkSize; 00316 FILETIME ftLastWriteTime; 00317 DWORD dwLength, dwType; 00318 DWORD dwDisposition; 00319 INT iStyle, iSize, iTemplateIndex; 00320 INT Result; 00321 00322 lstrcpy(pszSelectedStyle, TEXT("")); 00323 00324 iTemplateIndex = 0; 00325 Result = RegCreateKeyEx(HKEY_CURRENT_USER, g_CPANewSchemes, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkNewSchemes, &dwDisposition); 00326 if (Result == ERROR_SUCCESS) 00327 { 00328 /* First find out the currently selected template */ 00329 dwLength = 4 * sizeof(TCHAR); 00330 RegQueryValueEx(hkNewSchemes, g_SelectedStyle, NULL, &dwType, (LPBYTE)pszSelectedStyle, &dwLength); 00331 00332 /* Check if already loaded */ 00333 if (g_PresetLoaded) 00334 { 00335 RegCloseKey(hkNewSchemes); 00336 return g_TemplateCount; 00337 } 00338 00339 iStyle = 0; 00340 dwLength = MAX_TEMPLATENAMELENTGH; 00341 while((RegEnumKeyEx(hkNewSchemes, iStyle, g_ColorSchemes[iTemplateIndex].strKeyName, &dwLength, 00342 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iTemplateIndex < MAX_TEMPLATES)) 00343 { 00344 /* Is it really a template or one of the other entries */ 00345 if (dwLength <= 4) 00346 { 00347 if (RegOpenKeyEx(hkNewSchemes, g_ColorSchemes[iTemplateIndex].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS) 00348 { 00349 if (RegOpenKeyEx(hkScheme, TEXT("Sizes"), 0, KEY_READ, &hkSizes) == ERROR_SUCCESS) 00350 { 00351 iSize = 0; 00352 dwLength = 3; 00353 while((RegEnumKeyEx(hkSizes, iSize, g_ColorSchemes[iTemplateIndex].strSizeName, &dwLength, 00354 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iSize <= 4)) 00355 { 00356 if(RegOpenKeyEx(hkSizes, g_ColorSchemes[iTemplateIndex].strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS) 00357 { 00358 dwLength = MAX_TEMPLATENAMELENTGH; 00359 RegQueryValueEx(hkSize, TEXT("DisplayName"), NULL, &dwType, (LPBYTE)&g_ColorSchemes[iTemplateIndex].strDisplayName, &dwLength); 00360 dwLength = MAX_TEMPLATENAMELENTGH; 00361 RegQueryValueEx(hkSize, TEXT("LegacyName"), NULL, &dwType, (LPBYTE)&g_ColorSchemes[iTemplateIndex].strLegacyName, &dwLength); 00362 RegCloseKey(hkSize); 00363 } 00364 iSize++; 00365 iTemplateIndex++; 00366 dwLength = 3; 00367 } 00368 RegCloseKey(hkSizes); 00369 } 00370 RegCloseKey(hkScheme); 00371 } 00372 } 00373 iStyle++; 00374 dwLength = MAX_TEMPLATENAMELENTGH; 00375 } 00376 RegCloseKey(hkNewSchemes); 00377 g_PresetLoaded = TRUE; 00378 g_TemplateCount = iTemplateIndex; 00379 } 00380 return iTemplateIndex; 00381 } 00382 00383 typedef HRESULT (WINAPI * ENUMTHEMESTYLE) (LPCWSTR, LPWSTR, DWORD, PTHEMENAMES); 00384 00385 BOOL AddThemeStyles(LPCWSTR pszThemeFileName, HDSA* Styles, int* count, ENUMTHEMESTYLE enumTheme) 00386 { 00387 DWORD index = 0; 00388 THEMENAMES names; 00389 THEME_STYLE StyleName; 00390 00391 *Styles = DSA_Create(sizeof(THEMENAMES),1); 00392 *count = 0; 00393 00394 while (SUCCEEDED (enumTheme (pszThemeFileName, NULL, index++, &names))) 00395 { 00396 StyleName.StlyeName = _wcsdup(names.szName); 00397 StyleName.DisplayName = _wcsdup(names.szDisplayName); 00398 (*count)++; 00399 DSA_InsertItem(*Styles, *count, &StyleName); 00400 } 00401 00402 return TRUE; 00403 } 00404 00405 BOOL CALLBACK EnumThemeProc(LPVOID lpReserved, 00406 LPCWSTR pszThemeFileName, 00407 LPCWSTR pszThemeName, 00408 LPCWSTR pszToolTip, LPVOID lpReserved2, 00409 LPVOID lpData) 00410 { 00411 THEME theme; 00412 GLOBALS *g = (GLOBALS *) lpData; 00413 00414 theme.themeFileName = _wcsdup(pszThemeFileName); 00415 theme.displayName = _wcsdup(pszThemeName); 00416 AddThemeStyles( pszThemeFileName, &theme.Sizes, &theme.SizesCount, (ENUMTHEMESTYLE)EnumThemeSizes); 00417 AddThemeStyles( pszThemeFileName, &theme.Colors, &theme.ColorsCount, (ENUMTHEMESTYLE)EnumThemeColors); 00418 00419 DSA_InsertItem(g->Themes, DSA_APPEND , &theme); 00420 g->ThemesCount++; 00421 00422 return TRUE; 00423 } 00424 00425 void LoadThemes(GLOBALS *g) 00426 { 00427 WCHAR themesPath[MAX_PATH]; 00428 HRESULT hret; 00429 THEME ClassicTheme; 00430 WCHAR szThemeFileName[MAX_PATH]; 00431 WCHAR szColorBuff[MAX_PATH]; 00432 WCHAR szSizeBuff[MAX_PATH]; 00433 00434 /* Initialize themes dsa */ 00435 g->Themes = DSA_Create(sizeof(THEME),5); 00436 00437 /* Insert the classic theme */ 00438 memset(&ClassicTheme, 0, sizeof(THEME)); 00439 ClassicTheme.displayName = _wcsdup(L"Classic Theme"); 00440 DSA_InsertItem(g->Themes, 0, &ClassicTheme); 00441 g->ThemesCount = 1; 00442 00443 /* Retrieve the name of the current theme */ 00444 hret = GetCurrentThemeName(szThemeFileName, 00445 MAX_PATH, 00446 szColorBuff, 00447 MAX_PATH, 00448 szSizeBuff, 00449 MAX_PATH); 00450 00451 if (FAILED (hret)) 00452 { 00453 g->pszThemeFileName = NULL; 00454 g->pszColorName = NULL; 00455 g->pszSizeName = NULL; 00456 } 00457 else 00458 { 00459 /* Cache the name of the active theme */ 00460 g->pszThemeFileName = _wcsdup(szThemeFileName); 00461 g->pszColorName = _wcsdup(szColorBuff); 00462 g->pszSizeName = _wcsdup(szSizeBuff); 00463 } 00464 /* Get path to themes folder */ 00465 hret = SHGetFolderPathW (NULL, CSIDL_RESOURCES, NULL, SHGFP_TYPE_CURRENT, themesPath); 00466 if (FAILED (hret)) 00467 return; 00468 lstrcatW (themesPath, L"\\Themes"); 00469 00470 /* Enumerate themes */ 00471 hret = EnumThemes(themesPath, EnumThemeProc, g); 00472 } 00473 00474 HRESULT ActivateTheme(PTHEME pTheme, int iColor, int iSize) 00475 { 00476 PTHEME_STYLE pThemeColor; 00477 PTHEME_STYLE pThemeSize; 00478 HTHEMEFILE hThemeFile = 0; 00479 HRESULT hret; 00480 00481 if(pTheme->themeFileName) 00482 { 00483 pThemeColor = (PTHEME_STYLE)DSA_GetItemPtr(pTheme->Colors, iColor); 00484 pThemeSize = (PTHEME_STYLE)DSA_GetItemPtr(pTheme->Sizes, iSize); 00485 00486 hret = OpenThemeFile(pTheme->themeFileName, 00487 pThemeColor->StlyeName, 00488 pThemeSize->StlyeName, 00489 &hThemeFile, 00490 0); 00491 00492 if(!SUCCEEDED(hret)) 00493 { 00494 return hret; 00495 } 00496 00497 } 00498 00499 hret = ApplyTheme(hThemeFile, "", 0); 00500 00501 if(pTheme->themeFileName) 00502 { 00503 hret = CloseThemeFile(hThemeFile); 00504 } 00505 00506 return hret; 00507 } 00508 00509 int CALLBACK CleanUpThemeStlyeCallback(void *p, void *pData) 00510 { 00511 PTHEME_STYLE pStyle = (PTHEME_STYLE)p; 00512 00513 free(pStyle->DisplayName); 00514 free(pStyle->StlyeName); 00515 00516 return TRUE; 00517 } 00518 00519 int CALLBACK CleanUpThemeCallback(void *p, void *pData) 00520 { 00521 PTHEME pTheme = (PTHEME)p; 00522 00523 free(pTheme->displayName); 00524 free(pTheme->themeFileName); 00525 DSA_DestroyCallback(pTheme->Colors, CleanUpThemeStlyeCallback, NULL); 00526 DSA_DestroyCallback(pTheme->Sizes, CleanUpThemeStlyeCallback, NULL); 00527 00528 return TRUE; 00529 } 00530 00531 void CleanupThemes(GLOBALS *g) 00532 { 00533 free(g->pszThemeFileName); 00534 free(g->pszColorName); 00535 free(g->pszSizeName); 00536 00537 DSA_DestroyCallback(g->Themes, CleanUpThemeCallback, NULL); 00538 } Generated on Sat May 26 2012 04:19:44 for ReactOS by
1.7.6.1
|