Sync with trunk head (r49139)
[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_PresetLoaded = 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_GETDRAGFULLWINDOWS, 0, &theme->Effects.bDragFullWindows, 0);
128
129 /* "Hide underlined letters for keyboard navigation until I press the Alt key" */
130 SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &theme->Effects.bKeyboardCues, 0);
131 }
132
133 BOOL LoadThemeFromReg(THEME* theme, INT ThemeId)
134 {
135 INT i;
136 TCHAR strSelectedStyle[4];
137 TCHAR strSizeName[20] = {TEXT("Sizes\\0")};
138 TCHAR strValueName[10];
139 HKEY hkNewSchemes, hkScheme, hkSize;
140 DWORD dwType, dwLength;
141 BOOL Ret = FALSE;
142
143 if (!g_PresetLoaded)
144 LoadThemePresetEntries(strSelectedStyle);
145
146 if (ThemeId == -1)
147 return FALSE;
148
149 if (RegOpenKeyEx(HKEY_CURRENT_USER, g_CPANewSchemes, 0, KEY_READ, &hkNewSchemes) == ERROR_SUCCESS)
150 {
151 if (RegOpenKeyEx(hkNewSchemes, g_ThemeTemplates[ThemeId].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS)
152 {
153 lstrcpyn(&strSizeName[6], g_ThemeTemplates[ThemeId].strSizeName, 3);
154 if (RegOpenKeyEx(hkScheme, strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS)
155 {
156 Ret = TRUE;
157
158 dwLength = sizeof(DWORD);
159 if (RegQueryValueEx(hkSize, TEXT("FlatMenus"), NULL, &dwType, (LPBYTE)&theme->bFlatMenus, &dwLength) != ERROR_SUCCESS ||
160 dwType != REG_DWORD)
161 {
162 /* Failed to read registry value */
163 theme->bFlatMenus = FALSE;
164 }
165
166 for (i = 0; i < NUM_COLORS; i++)
167 {
168 wsprintf(strValueName, TEXT("Color #%d"), i);
169 dwLength = sizeof(COLORREF);
170 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&theme->crColor[i], &dwLength) != ERROR_SUCCESS ||
171 dwType != REG_DWORD)
172 {
173 /* Failed to read registry value, initialize with current setting for now */
174 theme->crColor[i] = GetSysColor(i);
175 }
176 }
177
178 for (i = 0; i < NUM_FONTS; i++)
179 {
180 wsprintf(strValueName, TEXT("Font #%d"), i);
181 dwLength = sizeof(LOGFONT);
182 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&theme->lfFont[i], &dwLength) != ERROR_SUCCESS ||
183 dwType != REG_BINARY || dwLength != sizeof(LOGFONT))
184 {
185 /* Failed to read registry value */
186 Ret = FALSE;
187 }
188 }
189
190 for (i = 0; i < NUM_SIZES; i++)
191 {
192 wsprintf(strValueName, TEXT("Size #%d"), i);
193 dwLength = sizeof(UINT64);
194 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&theme->Size[i], &dwLength) != ERROR_SUCCESS ||
195 dwType != REG_QWORD || dwLength != sizeof(UINT64))
196 {
197 /* Failed to read registry value, initialize with current setting for now */
198 theme->Size[i] = GetSystemMetrics(g_SizeMetric[i]);
199 }
200 }
201 RegCloseKey(hkScheme);
202 }
203 RegCloseKey(hkScheme);
204 }
205 RegCloseKey(hkNewSchemes);
206 }
207
208 return Ret;
209 }
210
211 static VOID
212 _UpdateUserPref(UINT SpiGet, UINT SpiSet, BOOL *pbFlag)
213 {
214 SystemParametersInfo(SpiSet, 0, (PVOID)pbFlag, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
215 }
216 #define UPDATE_USERPREF(NAME,pbFlag) _UpdateUserPref(SPI_GET ## NAME, SPI_SET ## NAME, pbFlag)
217
218 VOID ApplyTheme(THEME* theme, INT ThemeId)
219 {
220 INT i, Result;
221 HKEY hKey;
222 DWORD dwDisposition;
223 TCHAR clText[16];
224 NONCLIENTMETRICS NonClientMetrics;
225
226 /* Apply Colors from global variable */
227 SetSysColors(NUM_COLORS, g_ColorList, theme->crColor);
228
229 /* Save colors to registry */
230 Result = RegOpenKeyEx(HKEY_CURRENT_USER, g_CPColors, 0, KEY_ALL_ACCESS, &hKey);
231 if (Result != ERROR_SUCCESS)
232 {
233 /* Could not open the key, try to create it */
234 Result = RegCreateKeyEx(HKEY_CURRENT_USER, g_CPColors, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
235 }
236
237 if (Result == ERROR_SUCCESS)
238 {
239 for (i = 0; i < NUM_COLORS; i++)
240 {
241 DWORD red = GetRValue(theme->crColor[i]);
242 DWORD green = GetGValue(theme->crColor[i]);
243 DWORD blue = GetBValue(theme->crColor[i]);
244 wsprintf(clText, TEXT("%d %d %d"), red, green, blue);
245 RegSetValueEx(hKey, g_RegColorNames[i], 0, REG_SZ, (BYTE *)clText, (lstrlen(clText) + 1) * sizeof(TCHAR));
246 }
247 RegCloseKey(hKey);
248 }
249
250 /* Apply the fonts */
251 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);
252 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
253 NonClientMetrics.lfCaptionFont = theme->lfFont[FONT_CAPTION];
254 NonClientMetrics.lfSmCaptionFont = theme->lfFont[FONT_SMCAPTION];
255 NonClientMetrics.lfMenuFont = theme->lfFont[FONT_MENU];
256 NonClientMetrics.lfStatusFont = theme->lfFont[FONT_INFO];
257 NonClientMetrics.lfMessageFont = theme->lfFont[FONT_DIALOG];
258 SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
259 SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(LOGFONT), &theme->lfFont[FONT_ICON], 0);
260
261 /* FIXME: Apply size metrics */
262
263 /* Save fonts and size metrics to registry */
264 Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
265 if (Result == ERROR_SUCCESS)
266 {
267 RegSetValueEx(hKey, TEXT("CaptionFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_CAPTION], sizeof(LOGFONT));
268 RegSetValueEx(hKey, TEXT("SmCaptionFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_SMCAPTION], sizeof(LOGFONT));
269 RegSetValueEx(hKey, TEXT("IconFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_ICON], sizeof(LOGFONT));
270 RegSetValueEx(hKey, TEXT("MenuFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_MENU], sizeof(LOGFONT));
271 RegSetValueEx(hKey, TEXT("StatusFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_INFO], sizeof(LOGFONT));
272 RegSetValueEx(hKey, TEXT("MessageFont"), 0, REG_BINARY, (BYTE *)&theme->lfFont[FONT_DIALOG], sizeof(LOGFONT));
273
274 /* Save size metrics to registry */
275 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_BORDER_X]);
276 RegSetValueEx(hKey, TEXT("BorderWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
277 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_CAPTION_Y]);
278 RegSetValueEx(hKey, TEXT("CaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
279 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_CAPTION_Y]);
280 RegSetValueEx(hKey, TEXT("CaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
281 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_SMCAPTION_Y]);
282 RegSetValueEx(hKey, TEXT("SmCaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
283 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_SMCAPTION_Y]);
284 RegSetValueEx(hKey, TEXT("SmCaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
285 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_ICON_SPC_X]);
286 RegSetValueEx(hKey, TEXT("IconSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
287 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_ICON_SPC_Y]);
288 RegSetValueEx(hKey, TEXT("IconVerticalSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
289 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_MENU_SIZE_X]);
290 RegSetValueEx(hKey, TEXT("MenuWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
291 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_MENU_Y]);
292 RegSetValueEx(hKey, TEXT("MenuHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
293 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_SCROLL_X]);
294 RegSetValueEx(hKey, TEXT("ScrollWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
295 wsprintf(clText, TEXT("%d"), -15 * theme->Size[SIZE_SCROLL_Y]);
296 RegSetValueEx(hKey, TEXT("ScrollHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
297 wsprintf(clText, TEXT("%d"), theme->Size[SIZE_ICON_X]);
298 RegSetValueEx(hKey, TEXT("Shell Icon Size"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
299
300 RegCloseKey(hKey);
301 }
302
303 /* Effects, save only when needed: */
304 /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings
305 * Just keep them in sync for now.
306 */
307 theme->Effects.bTooltipAnimation = theme->Effects.bMenuAnimation;
308 theme->Effects.bTooltipFade = theme->Effects.bMenuFade;
309 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, theme->Effects.bDragFullWindows, (PVOID)&theme->Effects.bDragFullWindows, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
310 UPDATE_USERPREF(KEYBOARDCUES, &theme->Effects.bKeyboardCues);
311 //UPDATE_USERPREF(ACTIVEWINDOWTRACKING, &theme->Effects.bActiveWindowTracking);
312 //UPDATE_USERPREF(MENUANIMATION, &theme->Effects.bMenuAnimation);
313 //UPDATE_USERPREF(COMBOBOXANIMATION, &theme->Effects.bComboBoxAnimation);
314 //UPDATE_USERPREF(LISTBOXSMOOTHSCROLLING, &theme->Effects.bListBoxSmoothScrolling);
315 //UPDATE_USERPREF(GRADIENTCAPTIONS, &theme->Effects.bGradientCaptions);
316 //UPDATE_USERPREF(ACTIVEWNDTRKZORDER, &theme->Effects.bActiveWndTrkZorder);
317 //UPDATE_USERPREF(HOTTRACKING, &theme->Effects.bHotTracking);
318 UPDATE_USERPREF(MENUFADE, &theme->Effects.bMenuFade);
319 //UPDATE_USERPREF(SELECTIONFADE, &theme->Effects.bSelectionFade);
320 UPDATE_USERPREF(TOOLTIPANIMATION, &theme->Effects.bTooltipAnimation);
321 UPDATE_USERPREF(TOOLTIPFADE, &theme->Effects.bTooltipFade);
322 //UPDATE_USERPREF(CURSORSHADOW, &theme->Effects.bCursorShadow);
323 //UPDATE_USERPREF(UIEFFECTS, &theme->Effects.bUiEffects);
324
325 /* Save ThemeId */
326 Result = RegOpenKeyEx(HKEY_CURRENT_USER, g_CPANewSchemes, 0, KEY_ALL_ACCESS, &hKey);
327 if (Result == ERROR_SUCCESS)
328 {
329 if (ThemeId == -1)
330 clText[0] = TEXT('\0');
331 else
332 lstrcpy(clText, g_ThemeTemplates[ThemeId].strKeyName);
333 RegSetValueEx(hKey, g_SelectedStyle, 0, REG_SZ, (BYTE *)clText, (lstrlen(clText) + 1) * sizeof(TCHAR));
334 RegCloseKey(hKey);
335 }
336 }
337
338 BOOL SaveTheme(THEME* theme, LPCTSTR strLegacyName)
339 {
340 /* FIXME: implement */
341 return FALSE;
342 }
343
344 INT LoadThemePresetEntries(LPTSTR pszSelectedStyle)
345 {
346 HKEY hkNewSchemes, hkScheme, hkSizes, hkSize;
347 FILETIME ftLastWriteTime;
348 DWORD dwLength, dwType;
349 DWORD dwDisposition;
350 INT iStyle, iSize, iTemplateIndex;
351 INT Result;
352
353 lstrcpy(pszSelectedStyle, TEXT(""));
354
355 iTemplateIndex = 0;
356 Result = RegCreateKeyEx(HKEY_CURRENT_USER, g_CPANewSchemes, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkNewSchemes, &dwDisposition);
357 if (Result == ERROR_SUCCESS)
358 {
359 /* First find out the currently selected template */
360 dwLength = 4 * sizeof(TCHAR);
361 RegQueryValueEx(hkNewSchemes, g_SelectedStyle, NULL, &dwType, (LPBYTE)pszSelectedStyle, &dwLength);
362
363 /* Check if already loaded */
364 if (g_PresetLoaded)
365 {
366 RegCloseKey(hkNewSchemes);
367 return g_TemplateCount;
368 }
369
370 iStyle = 0;
371 dwLength = MAX_TEMPLATENAMELENTGH;
372 while((RegEnumKeyEx(hkNewSchemes, iStyle, g_ThemeTemplates[iTemplateIndex].strKeyName, &dwLength,
373 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iTemplateIndex < MAX_TEMPLATES))
374 {
375 /* is it really a template or one of the other entries */
376 if (dwLength <= 4)
377 {
378 if (RegOpenKeyEx(hkNewSchemes, g_ThemeTemplates[iTemplateIndex].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS)
379 {
380 if (RegOpenKeyEx(hkScheme, TEXT("Sizes"), 0, KEY_READ, &hkSizes) == ERROR_SUCCESS)
381 {
382 iSize = 0;
383 dwLength = 3;
384 while((RegEnumKeyEx(hkSizes, iSize, g_ThemeTemplates[iTemplateIndex].strSizeName, &dwLength,
385 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iSize <= 4))
386 {
387 if(RegOpenKeyEx(hkSizes, g_ThemeTemplates[iTemplateIndex].strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS)
388 {
389 dwLength = MAX_TEMPLATENAMELENTGH;
390 RegQueryValueEx(hkSize, TEXT("DisplayName"), NULL, &dwType, (LPBYTE)&g_ThemeTemplates[iTemplateIndex].strDisplayName, &dwLength);
391 dwLength = MAX_TEMPLATENAMELENTGH;
392 RegQueryValueEx(hkSize, TEXT("LegacyName"), NULL, &dwType, (LPBYTE)&g_ThemeTemplates[iTemplateIndex].strLegacyName, &dwLength);
393 RegCloseKey(hkSize);
394 }
395 iSize++;
396 iTemplateIndex++;
397 dwLength = 3;
398 }
399 RegCloseKey(hkSizes);
400 }
401 RegCloseKey(hkScheme);
402 }
403 }
404 iStyle++;
405 dwLength = MAX_TEMPLATENAMELENTGH;
406 }
407 RegCloseKey(hkNewSchemes);
408 g_PresetLoaded = TRUE;
409 g_TemplateCount = iTemplateIndex;
410 }
411 return iTemplateIndex;
412 }