sync with trunk (r46275)
[reactos.git] / dll / cpl / desk / appearance.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS Display Control Panel
5 * FILE: lib/cpl/desk/appearance.c
6 * PURPOSE: Appearance property page
7 *
8 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
9 * Timo Kreuzer (timo[dot]kreuzer[at]web[dot]de
10 */
11
12 #include "desk.h"
13 #include "appearance.h"
14
15 /******************************************************************************/
16
17 /* This const assigns the color and metric numbers to the elements from the elements list */
18
19 /* Size 1 (width) Size 2 (height) Color 1 Color 2 Font Fontcolor */
20 const ASSIGNMENT g_Assignment[NUM_ELEMENTS] =
21 { {-1, -1, COLOR_DESKTOP, -1, -1, -1}, /* -Desktop */
22 {SIZE_CAPTION_Y, -1, COLOR_INACTIVECAPTION, COLOR_GRADIENTINACTIVECAPTION, FONT_CAPTION, -1}, /* inactive window caption */
23 {SIZE_BORDER_X, SIZE_BORDER_Y, COLOR_INACTIVEBORDER, -1, -1, -1}, /* inactive window border */
24 {SIZE_CAPTION_Y, -1, COLOR_ACTIVECAPTION, COLOR_GRADIENTACTIVECAPTION, FONT_CAPTION, COLOR_CAPTIONTEXT}, /* -active window caption */
25 {SIZE_BORDER_X, SIZE_BORDER_Y, COLOR_ACTIVEBORDER, -1, -1, -1}, /* active window border */
26 {SIZE_MENU_X, SIZE_MENU_Y, COLOR_MENU, -1, FONT_MENU, COLOR_MENUTEXT}, /* menu */
27 {SIZE_MENU_X, SIZE_MENU_Y, COLOR_HIGHLIGHT, -1, FONT_HILIGHT, COLOR_HIGHLIGHTTEXT},/* marked element */
28 {-1, -1, COLOR_WINDOW, -1 /*COLOR_WINDOWFRAME*/, -1, COLOR_WINDOWTEXT}, /* window */
29 {SIZE_SCROLL_X, SIZE_SCROLL_Y, COLOR_SCROLLBAR, -1, -1, -1}, /* scroll bar */
30 {-1, -1, COLOR_3DFACE, -1, -1, COLOR_BTNTEXT}, /* 3d objects */
31 {SIZE_SMCAPTION_Y,-1, -1, -1, FONT_SMCAPTION, -1}, /* palette window caption */
32 {-1, -1, -1, -1, -1, -1}, /* symbol caption FIXME: Access? */
33 {SIZE_CAPTION_Y, -1, -1, -1, -1, -1}, /* caption bar */
34 {-1, -1, -1, -1, -1, COLOR_GRAYTEXT}, /* inactive menu item FIXME: Access? */
35 {-1, -1, -1, -1, FONT_DIALOG, COLOR_WINDOWTEXT}, /* dialog */
36 {-1, -1, -1, -1, -1, -1}, /* scrollbar controls FIXME: Access? */
37 {-1, -1, COLOR_APPWORKSPACE, -1, -1, -1}, /* application background */
38 {-1, -1, -1, -1, -1, -1}, /* small caption bar FIXME: Access? */
39 {SIZE_ICON_SPC_X, -1, -1, -1, -1, -1}, /* symbol distance horiz. */
40 {SIZE_ICON_SPC_Y, -1, -1, -1, -1, -1}, /* symbol distance vert. */
41 {-1, -1, COLOR_INFOBK, -1, FONT_INFO, COLOR_INFOTEXT}, /* quickinfo */
42 {SIZE_ICON_X, SIZE_ICON_Y, -1, -1, FONT_ICON, -1}}; /* symbol */
43
44 /* This is the list of names for the colors stored in the registry */
45 const TCHAR g_RegColorNames[NUM_COLORS][MAX_COLORNAMELENGTH] =
46 {TEXT("Scrollbar"), /* 00 = COLOR_SCROLLBAR */
47 TEXT("Background"), /* 01 = COLOR_DESKTOP */
48 TEXT("ActiveTitle"), /* 02 = COLOR_ACTIVECAPTION */
49 TEXT("InactiveTitle"), /* 03 = COLOR_INACTIVECAPTION */
50 TEXT("Menu"), /* 04 = COLOR_MENU */
51 TEXT("Window"), /* 05 = COLOR_WINDOW */
52 TEXT("WindowFrame"), /* 06 = COLOR_WINDOWFRAME */
53 TEXT("MenuText"), /* 07 = COLOR_MENUTEXT */
54 TEXT("WindowText"), /* 08 = COLOR_WINDOWTEXT */
55 TEXT("TitleText"), /* 09 = COLOR_CAPTIONTEXT */
56 TEXT("ActiveBorder"), /* 10 = COLOR_ACTIVEBORDER */
57 TEXT("InactiveBorder"), /* 11 = COLOR_INACTIVEBORDER */
58 TEXT("AppWorkSpace"), /* 12 = COLOR_APPWORKSPACE */
59 TEXT("Hilight"), /* 13 = COLOR_HIGHLIGHT */
60 TEXT("HilightText"), /* 14 = COLOR_HIGHLIGHTTEXT */
61 TEXT("ButtonFace"), /* 15 = COLOR_BTNFACE */
62 TEXT("ButtonShadow"), /* 16 = COLOR_BTNSHADOW */
63 TEXT("GrayText"), /* 17 = COLOR_GRAYTEXT */
64 TEXT("ButtonText"), /* 18 = COLOR_BTNTEXT */
65 TEXT("InactiveTitleText"), /* 19 = COLOR_INACTIVECAPTIONTEXT */
66 TEXT("ButtonHilight"), /* 20 = COLOR_BTNHIGHLIGHT */
67 TEXT("ButtonDkShadow"), /* 21 = COLOR_3DDKSHADOW */
68 TEXT("ButtonLight"), /* 22 = COLOR_3DLIGHT */
69 TEXT("InfoText"), /* 23 = COLOR_INFOTEXT */
70 TEXT("InfoWindow"), /* 24 = COLOR_INFOBK */
71 TEXT("ButtonAlternateFace"), /* 25 = COLOR_ALTERNATEBTNFACE */
72 TEXT("HotTrackingColor"), /* 26 = COLOR_HOTLIGHT */
73 TEXT("GradientActiveTitle"), /* 27 = COLOR_GRADIENTACTIVECAPTION */
74 TEXT("GradientInactiveTitle"), /* 28 = COLOR_GRADIENTINACTIVECAPTION */
75 TEXT("MenuHilight"), /* 29 = COLOR_MENUHILIGHT */
76 TEXT("MenuBar"), /* 30 = COLOR_MENUBAR */
77 };
78
79 /* This is the list of used metrics and their numbers */
80 const int g_SizeMetric[NUM_SIZES] =
81 {
82 SM_CXBORDER,
83 SM_CYBORDER,
84 SM_CYCAPTION,
85 SM_CXICON,
86 SM_CYICON,
87 SM_CXICONSPACING,
88 SM_CYICONSPACING,
89 SM_CXMENUSIZE,
90 SM_CYMENU,
91 SM_CXVSCROLL,
92 SM_CYHSCROLL,
93 SM_CYSMCAPTION
94 };
95
96 /******************************************************************************/
97
98 static VOID
99 LoadCurrentTheme(GLOBALS* g)
100 {
101 INT i;
102 NONCLIENTMETRICS NonClientMetrics;
103
104 g->Theme.bHasChanged = FALSE;
105 /* FIXME: it may be custom! */
106 g->Theme.bIsCustom = FALSE;
107
108 /* Load colors */
109 for (i = 0; i <= 30; i++)
110 {
111 g->ColorList[i] = i;
112 g->Theme.crColor[i] = (COLORREF)GetSysColor(i);
113 }
114
115 /* Load sizes */
116 for (i = 0; i <= 11; i++)
117 {
118 g->Theme.Size[i] = GetSystemMetrics(g_SizeMetric[i]);
119 }
120
121 /* Load fonts */
122 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);
123 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
124 g->Theme.lfFont[FONT_CAPTION] = NonClientMetrics.lfCaptionFont;
125 g->Theme.lfFont[FONT_SMCAPTION] = NonClientMetrics.lfSmCaptionFont;
126 g->Theme.lfFont[FONT_MENU] = NonClientMetrics.lfMenuFont;
127 g->Theme.lfFont[FONT_INFO] = NonClientMetrics.lfStatusFont;
128 g->Theme.lfFont[FONT_DIALOG] = NonClientMetrics.lfMessageFont;
129 SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &g->Theme.lfFont[FONT_ICON], 0);
130
131 /* Effects */
132 /* "Use the following transition effect for menus and tooltips" */
133 SystemParametersInfo(SPI_GETMENUANIMATION, sizeof(BOOL), &g->Theme.Effects.bMenuAnimation, 0);
134 SystemParametersInfo(SPI_GETMENUFADE, sizeof(BOOL), &g->Theme.Effects.bMenuFade, 0);
135 /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings
136 * Just keep them in sync for now:
137 */
138 g->Theme.Effects.bTooltipAnimation = g->Theme.Effects.bMenuAnimation;
139 g->Theme.Effects.bTooltipFade = g->Theme.Effects.bMenuFade;
140
141 /* show content of windows during dragging */
142 //SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, g->Theme.Effects.bDragFullWindows, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
143 SystemParametersInfoW(SPI_GETDRAGFULLWINDOWS, 0, &g->Theme.Effects.bDragFullWindows, 0);
144
145 /* "Hide underlined letters for keyboard navigation until I press the Alt key" */
146 SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &g->Theme.Effects.bKeyboardCues, 0);
147 }
148
149
150 static BOOL
151 LoadThemeFromReg(GLOBALS* g)
152 {
153 INT i;
154 TCHAR strSizeName[20] = {TEXT("Sizes\\0")};
155 TCHAR strValueName[10];
156 HKEY hkNewSchemes, hkScheme, hkSize;
157 DWORD dwType, dwLength;
158 BOOL Ret = FALSE;
159 INT iPreset = g->Theme.Id;
160
161 if(RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"),
162 0, KEY_READ, &hkNewSchemes) == ERROR_SUCCESS)
163 {
164 if(RegOpenKeyEx(hkNewSchemes, g->ThemeTemplates[iPreset].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS)
165 {
166 lstrcpyn(&strSizeName[6],g->ThemeTemplates[iPreset].strSizeName, 3);
167 if(RegOpenKeyEx(hkScheme, strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS)
168 {
169 Ret = TRUE;
170
171 dwLength = sizeof(DWORD);
172 if (RegQueryValueEx(hkSize, TEXT("FlatMenus"), NULL, &dwType, (LPBYTE)&g->Theme.bFlatMenus, &dwLength) != ERROR_SUCCESS ||
173 dwType != REG_DWORD || dwLength != sizeof(DWORD))
174 {
175 /* Failed to read registry value */
176 g->Theme.bFlatMenus = FALSE;
177 Ret = FALSE;
178 }
179
180 for (i = 0; i <= 30; i++)
181 {
182 wsprintf(strValueName, TEXT("Color #%d"), i);
183 dwLength = sizeof(COLORREF);
184 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&g->Theme.crColor[i], &dwLength) != ERROR_SUCCESS ||
185 dwType != REG_DWORD || dwLength != sizeof(COLORREF))
186 {
187 /* Failed to read registry value, initialize with current setting for now */
188 g->Theme.crColor[i] = GetSysColor(i);
189 Ret = FALSE;
190 }
191 }
192 for (i = 0; i <= 5; i++)
193 {
194 wsprintf(strValueName, TEXT("Font #%d"), i);
195 dwLength = sizeof(LOGFONT);
196 g->Theme.lfFont[i].lfFaceName[0] = 'x';
197 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&g->Theme.lfFont[i], &dwLength) != ERROR_SUCCESS ||
198 dwType != REG_BINARY || dwLength != sizeof(LOGFONT))
199 {
200 /* Failed to read registry value */
201 Ret = FALSE;
202 }
203 }
204 for (i = 0; i <= 8; i++)
205 {
206 wsprintf(strValueName, TEXT("Size #%d"), i);
207 dwLength = sizeof(UINT64);
208 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&g->Theme.Size[i], &dwLength) != ERROR_SUCCESS ||
209 dwType != REG_QWORD || dwLength != sizeof(UINT64))
210 {
211 /* Failed to read registry value, initialize with current setting for now */
212 g->Theme.Size[i] = GetSystemMetrics(g_SizeMetric[i]);
213 Ret = FALSE;
214 }
215 }
216 RegCloseKey(hkScheme);
217 }
218 RegCloseKey(hkScheme);
219 }
220 RegCloseKey(hkNewSchemes);
221 }
222
223 return Ret;
224 }
225
226 static VOID
227 _UpdateUserPref(UINT SpiGet,UINT SpiSet,BOOL *pbFlag)
228 {
229 SystemParametersInfo(SpiSet, 0, (PVOID)pbFlag, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
230 }
231 #define UPDATE_USERPREF(NAME,pbFlag) _UpdateUserPref(SPI_GET ## NAME, SPI_SET ## NAME, pbFlag)
232
233 static VOID
234 ApplyTheme(GLOBALS* g)
235 {
236 INT i, Result;
237 HKEY hKey;
238 DWORD dwDisposition = 0;
239 TCHAR clText[16] = {0};
240 NONCLIENTMETRICS NonClientMetrics;
241 HFONT hMyFont;
242 LOGFONT lfButtonFont;
243
244 if (!g->Theme.bHasChanged)
245 return;
246
247 /* Update some globals */
248 g->crCOLOR_BTNFACE = g->Theme.crColor[COLOR_BTNFACE];
249 g->crCOLOR_BTNTEXT = g->Theme.crColor[COLOR_BTNTEXT];
250 g->crCOLOR_BTNSHADOW = g->Theme.crColor[COLOR_BTNSHADOW];
251 g->crCOLOR_BTNHIGHLIGHT = g->Theme.crColor[COLOR_BTNHIGHLIGHT];
252 lfButtonFont = g->Theme.lfFont[FONT_DIALOG];
253
254 /* Create new font for bold button */
255 lfButtonFont.lfWeight = FW_BOLD;
256 lfButtonFont.lfItalic = FALSE;
257 hMyFont = CreateFontIndirect(&lfButtonFont);
258 if (hMyFont)
259 {
260 if (g->hBoldFont)
261 DeleteObject(g->hBoldFont);
262 g->hBoldFont = hMyFont;
263 }
264
265 /* Create new font for italic button */
266 lfButtonFont.lfWeight = FW_REGULAR;
267 lfButtonFont.lfItalic = TRUE;
268 hMyFont = CreateFontIndirect(&lfButtonFont);
269 if (hMyFont)
270 {
271 if (g->hItalicFont)
272 DeleteObject(g->hItalicFont);
273 g->hItalicFont = hMyFont;
274 }
275
276 /* Apply Colors from global variable */
277 SetSysColors(30, &g->ColorList[0], &g->Theme.crColor[0]);
278
279 /* Save colors to registry */
280 Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, KEY_ALL_ACCESS, &hKey);
281 if (Result != ERROR_SUCCESS)
282 {
283 /* Could not open the key, try to create it */
284 Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,&hKey, &dwDisposition);
285 }
286
287 if (Result == ERROR_SUCCESS)
288 {
289 for (i = 0; i <= 30; i++)
290 {
291 DWORD red = GetRValue(g->Theme.crColor[i]);
292 DWORD green = GetGValue(g->Theme.crColor[i]);
293 DWORD blue = GetBValue(g->Theme.crColor[i]);
294 wsprintf(clText, TEXT("%d %d %d"), red, green, blue);
295 RegSetValueEx(hKey, g_RegColorNames[i], 0, REG_SZ, (BYTE *)clText, lstrlen( clText )*sizeof(TCHAR) + sizeof(TCHAR));
296 }
297
298 RegCloseKey(hKey);
299 }
300
301 /* Apply the fonts */
302 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);
303 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
304 NonClientMetrics.lfCaptionFont = g->Theme.lfFont[FONT_CAPTION];
305 NonClientMetrics.lfSmCaptionFont = g->Theme.lfFont[FONT_SMCAPTION];
306 NonClientMetrics.lfMenuFont = g->Theme.lfFont[FONT_MENU];
307 NonClientMetrics.lfStatusFont = g->Theme.lfFont[FONT_INFO];
308 NonClientMetrics.lfMessageFont = g->Theme.lfFont[FONT_DIALOG];
309 SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
310 SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(LOGFONT), &g->Theme.lfFont[FONT_ICON], 0);
311
312 /* FIXME: Apply size metrics */
313
314 /* Save fonts and size metrics to registry */
315 Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, KEY_ALL_ACCESS, &hKey);
316 if (Result != ERROR_SUCCESS)
317 {
318 /* Could not open the key, try to create it */
319 Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,&hKey, &dwDisposition);
320 }
321
322 if (Result == ERROR_SUCCESS)
323 {
324 RegSetValueEx(hKey, TEXT("CaptionFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_CAPTION], sizeof(LOGFONT));
325 RegSetValueEx(hKey, TEXT("SmCaptionFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_SMCAPTION], sizeof(LOGFONT));
326 RegSetValueEx(hKey, TEXT("IconFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_ICON], sizeof(LOGFONT));
327 RegSetValueEx(hKey, TEXT("MenuFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_MENU], sizeof(LOGFONT));
328 RegSetValueEx(hKey, TEXT("StatusFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_INFO], sizeof(LOGFONT));
329 RegSetValueEx(hKey, TEXT("MessageFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_DIALOG], sizeof(LOGFONT));
330
331 /* Save size metrics to registry */
332 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_BORDER_X]);
333 RegSetValueEx(hKey, TEXT("BorderWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
334 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_CAPTION_Y]);
335 RegSetValueEx(hKey, TEXT("CaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
336 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_CAPTION_Y]);
337 RegSetValueEx(hKey, TEXT("CaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
338 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SMCAPTION_Y]);
339 RegSetValueEx(hKey, TEXT("SmCaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
340 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SMCAPTION_Y]);
341 RegSetValueEx(hKey, TEXT("SmCaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
342 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_ICON_SPC_X]);
343 RegSetValueEx(hKey, TEXT("IconSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
344 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_ICON_SPC_Y]);
345 RegSetValueEx(hKey, TEXT("IconVerticalSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
346 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_MENU_X]);
347 RegSetValueEx(hKey, TEXT("MenuWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
348 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_MENU_Y]);
349 RegSetValueEx(hKey, TEXT("MenuHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
350 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SCROLL_X]);
351 RegSetValueEx(hKey, TEXT("ScrollWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
352 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SCROLL_Y]);
353 RegSetValueEx(hKey, TEXT("ScrollHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
354 wsprintf(clText, TEXT("%d"), g->Theme.Size[SIZE_ICON_X]);
355 RegSetValueEx(hKey, TEXT("Shell Icon Sizet"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
356
357 RegCloseKey(hKey);
358 }
359
360 /* Effects, save only when needed: */
361 /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings
362 * Just keep them in sync for now.
363 */
364 g->Theme.Effects.bTooltipAnimation = g->Theme.Effects.bMenuAnimation;
365 g->Theme.Effects.bTooltipFade = g->Theme.Effects.bMenuFade;
366 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, g->Theme.Effects.bDragFullWindows, NULL, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
367 //UPDATE_USERPREF(KEYBOARDCUES, &g->Theme.Effects.bKeyboardCues);
368 //UPDATE_USERPREF(ACTIVEWINDOWTRACKING, &g->Theme.Effects.bActiveWindowTracking);
369 //UPDATE_USERPREF(MENUANIMATION, &g->Theme.Effects.bMenuAnimation);
370 //UPDATE_USERPREF(COMBOBOXANIMATION, &g->Theme.Effects.bComboBoxAnimation);
371 //UPDATE_USERPREF(LISTBOXSMOOTHSCROLLING, &g->Theme.Effects.bListBoxSmoothScrolling);
372 //UPDATE_USERPREF(GRADIENTCAPTIONS, &g->Theme.Effects.bGradientCaptions);
373 //UPDATE_USERPREF(ACTIVEWNDTRKZORDER, &g->Theme.Effects.bActiveWndTrkZorder);
374 //UPDATE_USERPREF(HOTTRACKING, &g->Theme.Effects.bHotTracking);
375 UPDATE_USERPREF(MENUFADE, &g->Theme.Effects.bMenuFade);
376 //UPDATE_USERPREF(SELECTIONFADE, &g->Theme.Effects.bSelectionFade);
377 UPDATE_USERPREF(TOOLTIPANIMATION, &g->Theme.Effects.bTooltipAnimation);
378 UPDATE_USERPREF(TOOLTIPFADE, &g->Theme.Effects.bTooltipFade);
379 //UPDATE_USERPREF(CURSORSHADOW, &g->Theme.Effects.bCursorShadow);
380 //UPDATE_USERPREF(UIEFFECTS, &g->Theme.Effects.bUiEffects);
381 /* Save ThemeId */
382 Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"), 0, KEY_ALL_ACCESS, &hKey);
383 if (Result == ERROR_SUCCESS)
384 {
385 lstrcpy(clText, g->ThemeTemplates[g->Theme.Id].strKeyName);
386 RegSetValueEx(hKey, TEXT("SelectedStyle"), 0, REG_SZ, (BYTE *)clText, (lstrlen(clText)+1) * sizeof (TCHAR));
387 RegCloseKey(hKey);
388 }
389 }
390
391
392 static INT_PTR
393 AppearancePage_OnInit(HWND hwndDlg, GLOBALS *g)
394 {
395 HKEY hkNewSchemes, hkScheme, hkSizes, hkSize;
396 FILETIME ftLastWriteTime;
397 TCHAR strSelectedStyle[4];
398 DWORD dwLength, dwType;
399 DWORD dwDisposition = 0;
400 INT iStyle, iSize, iTemplateIndex, iListIndex = 0;
401 INT Result;
402
403 g = (GLOBALS*)malloc(sizeof(GLOBALS));
404 if (g == NULL)
405 {
406 return FALSE;
407 }
408
409 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)g);
410
411 LoadCurrentTheme(g);
412
413 /* Fill color schemes combo */
414 Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"),
415 0, KEY_READ, &hkNewSchemes);
416 if (Result != ERROR_SUCCESS)
417 {
418 /* Could not open the key, try to create it */
419 Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,&hkNewSchemes, &dwDisposition);
420 if (Result == ERROR_SUCCESS)
421 {
422 /* FIXME: We have created it new, so let's put somethig there */
423 }
424 }
425 if (Result == ERROR_SUCCESS)
426 {
427 /* First find out the currently selected template */
428 dwLength = 8;
429 RegQueryValueEx(hkNewSchemes, TEXT("SelectedStyle"), NULL, &dwType, (LPBYTE)&strSelectedStyle, &dwLength);
430 iTemplateIndex = 0;
431 iStyle = 0;
432 dwLength = MAX_TEMPLATENAMELENTGH;
433 while((RegEnumKeyEx(hkNewSchemes, iStyle, g->ThemeTemplates[iTemplateIndex].strKeyName, &dwLength,
434 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iTemplateIndex < MAX_TEMPLATES))
435 {
436 /* is it really a template or one of the other entries */
437 if (dwLength < 5)
438 {
439 if (RegOpenKeyEx(hkNewSchemes, g->ThemeTemplates[iTemplateIndex].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS)
440 {
441 if(RegOpenKeyEx(hkScheme, TEXT("Sizes"), 0, KEY_READ, &hkSizes) == ERROR_SUCCESS)
442 {
443 iSize = 0;
444 dwLength = 3;
445 while((RegEnumKeyEx(hkSizes, iSize, g->ThemeTemplates[iTemplateIndex].strSizeName, &dwLength,
446 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iSize <= 4))
447 {
448 if(RegOpenKeyEx(hkSizes, g->ThemeTemplates[iTemplateIndex].strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS)
449 {
450 dwLength = MAX_TEMPLATENAMELENTGH;
451 RegQueryValueEx(hkSize, TEXT("DisplayName"), NULL, &dwType, (LPBYTE)&g->ThemeTemplates[iTemplateIndex].strDisplayName, &dwLength);
452 dwLength = MAX_TEMPLATENAMELENTGH;
453 RegQueryValueEx(hkSize, TEXT("LegacyName"), NULL, &dwType, (LPBYTE)&g->ThemeTemplates[iTemplateIndex].strLegacyName, &dwLength);
454 RegCloseKey(hkSize);
455 }
456 iListIndex = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_ADDSTRING, 0, (LPARAM)g->ThemeTemplates[iTemplateIndex].strLegacyName);
457 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_SETITEMDATA, iListIndex, iTemplateIndex);
458 if (lstrcmp(g->ThemeTemplates[iTemplateIndex].strKeyName, strSelectedStyle) == 0)
459 {
460 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_SETCURSEL, (WPARAM)iListIndex, 0);
461 }
462 iSize++;
463 iTemplateIndex++;
464 dwLength = 3;
465 }
466 RegCloseKey(hkSizes);
467 }
468 RegCloseKey(hkScheme);
469 }
470 }
471 iStyle++;
472 dwLength = MAX_TEMPLATENAMELENTGH;
473 }
474 RegCloseKey(hkNewSchemes);
475 }
476 SendMessage(GetDlgItem(hwndDlg, IDC_APPEARANCE_COLORSCHEME), LB_SETCURSEL, 0, 0);
477
478 return FALSE;
479 }
480
481
482 static INT_PTR
483 AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g)
484 {
485 free(g);
486 return TRUE;
487 }
488
489
490 INT_PTR CALLBACK
491 AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
492 {
493 INT i;
494 GLOBALS *g;
495 LPNMHDR lpnm;
496
497 g = (GLOBALS*)GetWindowLongPtr(hwndDlg, DWLP_USER);
498
499 switch (uMsg)
500 {
501 case WM_INITDIALOG:
502 return AppearancePage_OnInit(hwndDlg, g);
503
504 case WM_DESTROY:
505 return AppearancePage_OnDestroy(hwndDlg, g);
506
507 case WM_COMMAND:
508 switch (LOWORD(wParam))
509 {
510 case IDC_APPEARANCE_EFFECTS:
511 DialogBoxParam(hApplet, (LPCTSTR)IDD_EFFAPPEARANCE,
512 hwndDlg, EffAppearanceDlgProc, (LPARAM)g);
513
514 /* Was anything changed in the effects appearance dialog? */
515 if (memcmp(&g->Theme, &g->ThemeAdv, sizeof(THEME)) != 0)
516 {
517 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
518 g->Theme = g->ThemeAdv;
519 g->Theme.bHasChanged = TRUE;
520 }
521 break;
522
523 case IDC_APPEARANCE_ADVANCED:
524 DialogBoxParam(hApplet, (LPCTSTR)IDD_ADVAPPEARANCE,
525 hwndDlg, AdvAppearanceDlgProc, (LPARAM)g);
526
527 /* Was anything changed in the advanced appearance dialog? */
528 if (memcmp(&g->Theme, &g->ThemeAdv, sizeof(THEME)) != 0)
529 {
530 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
531 g->Theme = g->ThemeAdv;
532 g->Theme.bHasChanged = TRUE;
533 }
534 break;
535
536 case IDC_APPEARANCE_COLORSCHEME:
537 if(HIWORD(wParam) == CBN_SELCHANGE)
538 {
539 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
540 g->Theme.bHasChanged = TRUE;
541 i = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETCURSEL, 0, 0);
542 g->Theme.Id = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETITEMDATA, (WPARAM)i, 0);
543 LoadThemeFromReg(g);
544 //SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, WM_PAINT, 0, 0);
545 }
546 break;
547
548 default:
549 return FALSE;
550 }
551 return TRUE;
552
553 case WM_NOTIFY:
554 lpnm = (LPNMHDR)lParam;
555 switch (lpnm->code)
556 {
557 case PSN_APPLY:
558 if (g->Theme.bHasChanged)
559 {
560 ApplyTheme(g);
561 }
562 return TRUE;
563
564 default:
565 return FALSE;
566 }
567 return TRUE;
568
569 default:
570 return FALSE;
571 }
572
573 return TRUE;
574 }