0170fabb4fd578090fddb926bbe4aa6b76ab68e5
[reactos.git] / dll / cpl / desk / theme.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Display Control Panel
4 * FILE: lib/cpl/desk/theme.c
5 * PURPOSE: Handling themes
6 *
7 * PROGRAMMERS: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
8 */
9
10 #include "desk.h"
11 #include "theme.h"
12
13 static BOOL g_TemplateLoaded = FALSE;
14 static INT g_TemplateCount = 0;
15
16 static INT g_ColorList[NUM_COLORS];
17
18 static const TCHAR g_CPColors[] = TEXT("Control Panel\\Colors");
19 static const TCHAR g_CPANewSchemes[] = TEXT("Control Panel\\Appearance\\New Schemes");
20 static const TCHAR g_SelectedStyle[] = TEXT("SelectedStyle");
21
22 /******************************************************************************/
23
24 THEME_PRESET g_ThemeTemplates[MAX_TEMPLATES];
25
26 /* This is the list of names for the colors stored in the registry */
27 const TCHAR g_RegColorNames[NUM_COLORS][MAX_COLORNAMELENGTH] =
28 {TEXT("Scrollbar"), /* 00 = COLOR_SCROLLBAR */
29 TEXT("Background"), /* 01 = COLOR_DESKTOP */
30 TEXT("ActiveTitle"), /* 02 = COLOR_ACTIVECAPTION */
31 TEXT("InactiveTitle"), /* 03 = COLOR_INACTIVECAPTION */
32 TEXT("Menu"), /* 04 = COLOR_MENU */
33 TEXT("Window"), /* 05 = COLOR_WINDOW */
34 TEXT("WindowFrame"), /* 06 = COLOR_WINDOWFRAME */
35 TEXT("MenuText"), /* 07 = COLOR_MENUTEXT */
36 TEXT("WindowText"), /* 08 = COLOR_WINDOWTEXT */
37 TEXT("TitleText"), /* 09 = COLOR_CAPTIONTEXT */
38 TEXT("ActiveBorder"), /* 10 = COLOR_ACTIVEBORDER */
39 TEXT("InactiveBorder"), /* 11 = COLOR_INACTIVEBORDER */
40 TEXT("AppWorkSpace"), /* 12 = COLOR_APPWORKSPACE */
41 TEXT("Hilight"), /* 13 = COLOR_HIGHLIGHT */
42 TEXT("HilightText"), /* 14 = COLOR_HIGHLIGHTTEXT */
43 TEXT("ButtonFace"), /* 15 = COLOR_BTNFACE */
44 TEXT("ButtonShadow"), /* 16 = COLOR_BTNSHADOW */
45 TEXT("GrayText"), /* 17 = COLOR_GRAYTEXT */
46 TEXT("ButtonText"), /* 18 = COLOR_BTNTEXT */
47 TEXT("InactiveTitleText"), /* 19 = COLOR_INACTIVECAPTIONTEXT */
48 TEXT("ButtonHilight"), /* 20 = COLOR_BTNHIGHLIGHT */
49 TEXT("ButtonDkShadow"), /* 21 = COLOR_3DDKSHADOW */
50 TEXT("ButtonLight"), /* 22 = COLOR_3DLIGHT */
51 TEXT("InfoText"), /* 23 = COLOR_INFOTEXT */
52 TEXT("InfoWindow"), /* 24 = COLOR_INFOBK */
53 TEXT("ButtonAlternateFace"), /* 25 = COLOR_ALTERNATEBTNFACE */
54 TEXT("HotTrackingColor"), /* 26 = COLOR_HOTLIGHT */
55 TEXT("GradientActiveTitle"), /* 27 = COLOR_GRADIENTACTIVECAPTION */
56 TEXT("GradientInactiveTitle"), /* 28 = COLOR_GRADIENTINACTIVECAPTION */
57 TEXT("MenuHilight"), /* 29 = COLOR_MENUHILIGHT */
58 TEXT("MenuBar"), /* 30 = COLOR_MENUBAR */
59 };
60
61 /* This is the list of used metrics and their numbers */
62 const int g_SizeMetric[NUM_SIZES] =
63 {
64 SM_CXBORDER, /* 00: SIZE_BORDER_X */
65 SM_CYBORDER, /* 01: SIZE_BORDER_Y */
66 SM_CYCAPTION, /* 02: SIZE_CAPTION_Y */
67 SM_CXICON, /* 03: SIZE_ICON_X */
68 SM_CYICON, /* 04: SIZE_ICON_Y */
69 SM_CXICONSPACING, /* 05: SIZE_ICON_SPC_X */
70 SM_CYICONSPACING, /* 06: SIZE_ICON_SPC_Y */
71 SM_CXMENUSIZE, /* 07: SIZE_MENU_SIZE_X */
72 SM_CYMENU, /* 08: SIZE_MENU_Y */
73 SM_CXVSCROLL, /* 09: SIZE_SCROLL_X */
74 SM_CYHSCROLL, /* 10: SIZE_SCROLL_Y */
75 SM_CYSMCAPTION, /* 11: SIZE_SMCAPTION_Y */
76 SM_CXEDGE, /* 12: SIZE_EDGE_X */
77 SM_CYEDGE, /* 13: SIZE_EDGE_Y */
78 SM_CYSIZEFRAME, /* 14: SIZE_FRAME_Y */
79 SM_CXMENUCHECK, /* 15: SIZE_MENU_CHECK_X */
80 SM_CYMENUCHECK, /* 16: SIZE_MENU_CHECK_Y */
81 SM_CYMENUSIZE, /* 17: SIZE_MENU_SIZE_Y */
82 SM_CXSIZE, /* 18: SIZE_SIZE_X */
83 SM_CYSIZE /* 19: SIZE_SIZE_Y */
84 };
85
86 /******************************************************************************/
87
88 VOID LoadCurrentTheme(THEME* theme)
89 {
90 INT i;
91 NONCLIENTMETRICS NonClientMetrics;
92
93 /* Load colors */
94 for (i = 0; i < NUM_COLORS; i++)
95 {
96 g_ColorList[i] = i;
97 theme->crColor[i] = (COLORREF)GetSysColor(i);
98 }
99
100 /* Load sizes */
101 for (i = 0; i < NUM_SIZES; i++)
102 {
103 theme->Size[i] = GetSystemMetrics(g_SizeMetric[i]);
104 }
105
106 /* Load fonts */
107 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);
108 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
109 theme->lfFont[FONT_CAPTION] = NonClientMetrics.lfCaptionFont;
110 theme->lfFont[FONT_SMCAPTION] = NonClientMetrics.lfSmCaptionFont;
111 theme->lfFont[FONT_MENU] = NonClientMetrics.lfMenuFont;
112 theme->lfFont[FONT_INFO] = NonClientMetrics.lfStatusFont;
113 theme->lfFont[FONT_DIALOG] = NonClientMetrics.lfMessageFont;
114 SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &theme->lfFont[FONT_ICON], 0);
115
116 /* Effects */
117 /* "Use the following transition effect for menus and tooltips" */
118 SystemParametersInfo(SPI_GETMENUANIMATION, sizeof(BOOL), &theme->Effects.bMenuAnimation, 0);
119 SystemParametersInfo(SPI_GETMENUFADE, sizeof(BOOL), &theme->Effects.bMenuFade, 0);
120 /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings
121 * Just keep them in sync for now:
122 */
123 theme->Effects.bTooltipAnimation = theme->Effects.bMenuAnimation;
124 theme->Effects.bTooltipFade = theme->Effects.bMenuFade;
125
126 /* show content of windows during dragging */
127 //SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, theme->Effects.bDragFullWindows, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
128 SystemParametersInfoW(SPI_GETDRAGFULLWINDOWS, 0, &theme->Effects.bDragFullWindows, 0);
129
130 /* "Hide underlined letters for keyboard navigation until I press the Alt key" */
131 SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &theme->Effects.bKeyboardCues, 0);
132 }
133
134 BOOL LoadThemeFromReg(THEME* theme, INT ThemeId)
135 {
136 INT i;
137 TCHAR strSelectedStyle[4];
138 TCHAR strSizeName[20] = {TEXT("Sizes\\0")};
139 TCHAR strValueName[10];
140 HKEY hkNewSchemes, hkScheme, hkSize;
141 DWORD dwType, dwLength;
142 BOOL Ret = FALSE;
143
144 if (!g_TemplateLoaded)
145 LoadThemeTemplates(strSelectedStyle);
146
147 if (ThemeId == -1)
148 return FALSE;
149
150 if (RegOpenKeyEx(HKEY_CURRENT_USER, g_CPANewSchemes, 0, KEY_READ, &hkNewSchemes) == ERROR_SUCCESS)
151 {
152 if (RegOpenKeyEx(hkNewSchemes, g_ThemeTemplates[ThemeId].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS)
153 {
154 lstrcpyn(&strSizeName[6], g_ThemeTemplates[ThemeId].strSizeName, 3);
155 if (RegOpenKeyEx(hkScheme, strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS)
156 {
157 Ret = TRUE;
158
159 dwLength = sizeof(DWORD);
160 if (RegQueryValueEx(hkSize, TEXT("FlatMenus"), NULL, &dwType, (LPBYTE)&theme->bFlatMenus, &dwLength) != ERROR_SUCCESS ||
161 dwType != REG_DWORD)
162 {
163 /* Failed to read registry value */
164 theme->bFlatMenus = FALSE;
165 }
166
167 for (i = 0; i < NUM_COLORS; i++)
168 {
169 wsprintf(strValueName, TEXT("Color #%d"), i);
170 dwLength = sizeof(COLORREF);
171 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&theme->crColor[i], &dwLength) != ERROR_SUCCESS ||
172 dwType != REG_DWORD)
173 {
174 /* Failed to read registry value, initialize with current setting for now */
175 theme->crColor[i] = GetSysColor(i);
176 }
177 }
178
179 for (i = 0; i < NUM_FONTS; i++)
180 {
181 wsprintf(strValueName, TEXT("Font #%d"), i);
182 dwLength = sizeof(LOGFONT);
183 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&theme->lfFont[i], &dwLength) != ERROR_SUCCESS ||
184 dwType != REG_BINARY || dwLength != sizeof(LOGFONT))
185 {
186 /* Failed to read registry value */
187 Ret = FALSE;
188 }
189 }
190
191 for (i = 0; i < NUM_SIZES; i++)
192 {
193 wsprintf(strValueName, TEXT("Size #%d"), i);
194 dwLength = sizeof(UINT64);
195 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&theme->Size[i], &dwLength) != ERROR_SUCCESS ||
196 dwType != REG_QWORD || dwLength != sizeof(UINT64))
197 {
198 /* Failed to read registry value, initialize with current setting for now */
199 theme->Size[i] = GetSystemMetrics(g_SizeMetric[i]);
200 }
201 }
202 RegCloseKey(hkScheme);
203 }
204 RegCloseKey(hkScheme);
205 }
206 RegCloseKey(hkNewSchemes);
207 }
208
209 return Ret;
210 }
211
212 static VOID
213 _UpdateUserPref(UINT SpiGet, UINT SpiSet, BOOL *pbFlag)
214 {
215 SystemParametersInfo(SpiSet, 0, (PVOID)pbFlag, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
216 }
217 #define UPDATE_USERPREF(NAME,pbFlag) _UpdateUserPref(SPI_GET ## NAME, SPI_SET ## NAME, pbFlag)
218
219 VOID ApplyTheme(THEME* theme, INT ThemeId)
220 {
221 INT i, Result;
222 HKEY hKey;
223 DWORD dwDisposition;
224 TCHAR clText[16];
225 NONCLIENTMETRICS NonClientMetrics;
226
227 /* Apply Colors from global variable */
228 SetSysColors(NUM_COLORS, g_ColorList, theme->crColor);
229
230 /* Save colors to registry */
231 Result = RegOpenKeyEx(HKEY_CURRENT_USER, g_CPColors, 0, KEY_ALL_ACCESS, &hKey);
232 if (Result != ERROR_SUCCESS)
233 {
234 /* Could not open the key, try to create it */
235 Result = RegCreateKeyEx(HKEY_CURRENT_USER, g_CPColors, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
236 }
237
238 if (Result == ERROR_SUCCESS)
239 {
240 for (i = 0; i < NUM_COLORS; i++)
241 {
242 DWORD red = GetRValue(theme->crColor[i]);
243 DWORD green = GetGValue(theme->crColor[i]);
244 DWORD blue = GetBValue(theme->crColor[i]);
245 wsprintf(clText, TEXT("%d %d %d"), red, green, blue);
246 RegSetValueEx(hKey, g_RegColorNames[i], 0, REG_SZ, (BYTE *)clText, (lstrlen(clText) + 1) * sizeof(TCHAR));
247 }
248 RegCloseKey(hKey);
249 }
250
251 /* Apply the fonts */
252 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);
253 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
254 NonClientMetrics.lfCaptionFont = theme->lfFont[FONT_CAPTION];
255 NonClientMetrics.lfSmCaptionFont = theme->lfFont[FONT_SMCAPTION];
256 NonClientMetrics.lfMenuFont = theme->lfFont[FONT_MENU];
257 NonClientMetrics.lfStatusFont = theme->lfFont[FONT_INFO];
258 NonClientMetrics.lfMessageFont = theme->lfFont[FONT_DIALOG];
259 SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
260 SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(LOGFONT), &theme->lfFont[FONT_ICON], 0);
261
262 /* FIXME: Apply size metrics */
263
264 /* Save fonts and size metrics to registry */
265 Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
266 if (Result == ERROR_SUCCESS)
267 {
268 RegSetValueEx(hKey, TEXT("CaptionFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_CAPTION], sizeof(LOGFONT));
269 RegSetValueEx(hKey, TEXT("SmCaptionFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_SMCAPTION], sizeof(LOGFONT));
270 RegSetValueEx(hKey, TEXT("IconFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_ICON], sizeof(LOGFONT));
271 RegSetValueEx(hKey, TEXT("MenuFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_MENU], sizeof(LOGFONT));
272 RegSetValueEx(hKey, TEXT("StatusFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_INFO], sizeof(LOGFONT));
273 RegSetValueEx(hKey, TEXT("MessageFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_DIALOG], sizeof(LOGFONT));
274
275 /* Save size metrics to registry */
276 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_BORDER_X]);
277 RegSetValueEx(hKey, TEXT("BorderWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
278 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_CAPTION_Y]);
279 RegSetValueEx(hKey, TEXT("CaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
280 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_CAPTION_Y]);
281 RegSetValueEx(hKey, TEXT("CaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
282 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_SMCAPTION_Y]);
283 RegSetValueEx(hKey, TEXT("SmCaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
284 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_SMCAPTION_Y]);
285 RegSetValueEx(hKey, TEXT("SmCaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
286 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_ICON_SPC_X]);
287 RegSetValueEx(hKey, TEXT("IconSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
288 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_ICON_SPC_Y]);
289 RegSetValueEx(hKey, TEXT("IconVerticalSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
290 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_MENU_SIZE_X]);
291 RegSetValueEx(hKey, TEXT("MenuWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
292 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_MENU_Y]);
293 RegSetValueEx(hKey, TEXT("MenuHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
294 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_SCROLL_X]);
295 RegSetValueEx(hKey, TEXT("ScrollWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
296 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_SCROLL_Y]);
297 RegSetValueEx(hKey, TEXT("ScrollHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
298 wsprintf(clText, TEXT("%d"), theme->Size[SIZE_ICON_X]);
299 RegSetValueEx(hKey, TEXT("Shell Icon Size"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
300
301 RegCloseKey(hKey);
302 }
303
304 /* Effects, save only when needed: */
305 /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings
306 * Just keep them in sync for now.
307 */
308 theme->Effects.bTooltipAnimation = theme->Effects.bMenuAnimation;
309 theme->Effects.bTooltipFade = theme->Effects.bMenuFade;
310 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, theme->Effects.bDragFullWindows, NULL, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
311 UPDATE_USERPREF(KEYBOARDCUES, &theme->Effects.bKeyboardCues);
312 //UPDATE_USERPREF(ACTIVEWINDOWTRACKING, &theme->Effects.bActiveWindowTracking);
313 //UPDATE_USERPREF(MENUANIMATION, &theme->Effects.bMenuAnimation);
314 //UPDATE_USERPREF(COMBOBOXANIMATION, &theme->Effects.bComboBoxAnimation);
315 //UPDATE_USERPREF(LISTBOXSMOOTHSCROLLING, &theme->Effects.bListBoxSmoothScrolling);
316 //UPDATE_USERPREF(GRADIENTCAPTIONS, &theme->Effects.bGradientCaptions);
317 //UPDATE_USERPREF(ACTIVEWNDTRKZORDER, &theme->Effects.bActiveWndTrkZorder);
318 //UPDATE_USERPREF(HOTTRACKING, &theme->Effects.bHotTracking);
319 UPDATE_USERPREF(MENUFADE, &theme->Effects.bMenuFade);
320 //UPDATE_USERPREF(SELECTIONFADE, &theme->Effects.bSelectionFade);
321 UPDATE_USERPREF(TOOLTIPANIMATION, &theme->Effects.bTooltipAnimation);
322 UPDATE_USERPREF(TOOLTIPFADE, &theme->Effects.bTooltipFade);
323 //UPDATE_USERPREF(CURSORSHADOW, &theme->Effects.bCursorShadow);
324 //UPDATE_USERPREF(UIEFFECTS, &theme->Effects.bUiEffects);
325
326 /* Save ThemeId */
327 Result = RegOpenKeyEx(HKEY_CURRENT_USER, g_CPANewSchemes, 0, KEY_ALL_ACCESS, &hKey);
328 if (Result == ERROR_SUCCESS)
329 {
330 if (ThemeId == -1)
331 clText[0] = TEXT('\0');
332 else
333 lstrcpy(clText, g_ThemeTemplates[ThemeId].strKeyName);
334 RegSetValueEx(hKey, g_SelectedStyle, 0, REG_SZ, (BYTE *)clText, (lstrlen(clText) + 1) * sizeof(TCHAR));
335 RegCloseKey(hKey);
336 }
337 }
338
339 BOOL SaveTheme(THEME* theme, LPCTSTR strLegacyName)
340 {
341 /* FIXME: implement */
342 return FALSE;
343 }
344
345 INT LoadThemeTemplates(LPTSTR pszSelectedStyle)
346 {
347 HKEY hkNewSchemes, hkScheme, hkSizes, hkSize;
348 FILETIME ftLastWriteTime;
349 DWORD dwLength, dwType;
350 DWORD dwDisposition;
351 INT iStyle, iSize, iTemplateIndex;
352 INT Result;
353
354 lstrcpy(pszSelectedStyle, TEXT(""));
355
356 iTemplateIndex = 0;
357 Result = RegCreateKeyEx(HKEY_CURRENT_USER, g_CPANewSchemes, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkNewSchemes, &dwDisposition);
358 if (Result == ERROR_SUCCESS)
359 {
360 /* First find out the currently selected template */
361 dwLength = 4 * sizeof(TCHAR);
362 RegQueryValueEx(hkNewSchemes, g_SelectedStyle, NULL, &dwType, (LPBYTE)pszSelectedStyle, &dwLength);
363
364 /* Check if already loaded */
365 if (g_TemplateLoaded)
366 {
367 RegCloseKey(hkNewSchemes);
368 return g_TemplateCount;
369 }
370
371 iStyle = 0;
372 dwLength = MAX_TEMPLATENAMELENTGH;
373 while((RegEnumKeyEx(hkNewSchemes, iStyle, g_ThemeTemplates[iTemplateIndex].strKeyName, &dwLength,
374 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iTemplateIndex < MAX_TEMPLATES))
375 {
376 /* is it really a template or one of the other entries */
377 if (dwLength <= 4)
378 {
379 if (RegOpenKeyEx(hkNewSchemes, g_ThemeTemplates[iTemplateIndex].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS)
380 {
381 if (RegOpenKeyEx(hkScheme, TEXT("Sizes"), 0, KEY_READ, &hkSizes) == ERROR_SUCCESS)
382 {
383 iSize = 0;
384 dwLength = 3;
385 while((RegEnumKeyEx(hkSizes, iSize, g_ThemeTemplates[iTemplateIndex].strSizeName, &dwLength,
386 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iSize <= 4))
387 {
388 if(RegOpenKeyEx(hkSizes, g_ThemeTemplates[iTemplateIndex].strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS)
389 {
390 dwLength = MAX_TEMPLATENAMELENTGH;
391 RegQueryValueEx(hkSize, TEXT("DisplayName"), NULL, &dwType, (LPBYTE)&g_ThemeTemplates[iTemplateIndex].strDisplayName, &dwLength);
392 dwLength = MAX_TEMPLATENAMELENTGH;
393 RegQueryValueEx(hkSize, TEXT("LegacyName"), NULL, &dwType, (LPBYTE)&g_ThemeTemplates[iTemplateIndex].strLegacyName, &dwLength);
394 RegCloseKey(hkSize);
395 }
396 iSize++;
397 iTemplateIndex++;
398 dwLength = 3;
399 }
400 RegCloseKey(hkSizes);
401 }
402 RegCloseKey(hkScheme);
403 }
404 }
405 iStyle++;
406 dwLength = MAX_TEMPLATENAMELENTGH;
407 }
408 RegCloseKey(hkNewSchemes);
409 g_TemplateLoaded = TRUE;
410 g_TemplateCount = iTemplateIndex;
411 }
412 return iTemplateIndex;
413 }