1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Display Control Panel
4 * FILE: dll/cpl/desk/appearance.c
5 * PURPOSE: Appearance property page
6 *
7 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
8 * Timo Kreuzer (timo[dot]kreuzer[at]web[dot]de)
9 */
10
11 #include "desk.h"
12
13 /******************************************************************************/
14
15 static void
AppearancePage_UpdateThemePreview(HWND hwndDlg,GLOBALS * g)16 AppearancePage_UpdateThemePreview(HWND hwndDlg, GLOBALS *g)
17 {
18 if (g->ActiveTheme.ThemeActive)
19 {
20 RECT rcWindow;
21
22 GetClientRect(GetDlgItem(hwndDlg, IDC_APPEARANCE_PREVIEW), &rcWindow);
23 if (DrawThemePreview(g->hdcThemePreview, &g->Scheme, &g->ActiveTheme, &rcWindow))
24 {
25 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_SET_HDC_PREVIEW, 0, (LPARAM)g->hdcThemePreview);
26 return;
27 }
28 }
29
30 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_UPDATETHEME, 0, (LPARAM)&g->Scheme);
31 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_SET_HDC_PREVIEW, 0, 0);
32 }
33
34 static void
AppearancePage_LoadSelectedScheme(HWND hwndDlg,GLOBALS * g)35 AppearancePage_LoadSelectedScheme(HWND hwndDlg, GLOBALS *g)
36 {
37 if (g->ActiveTheme.ThemeActive == FALSE )
38 {
39 LoadSchemeFromReg(&g->Scheme, &g->ActiveTheme);
40 }
41 else
42 {
43 LoadSchemeFromTheme(&g->Scheme, &g->ActiveTheme);
44 }
45
46 g_GlobalData.desktop_color = g->Scheme.crColor[COLOR_DESKTOP];
47 }
48
49 static void
AppearancePage_ShowStyles(HWND hwndDlg,int nIDDlgItem,PTHEME_STYLE pStyles,PTHEME_STYLE pActiveStyle)50 AppearancePage_ShowStyles(HWND hwndDlg, int nIDDlgItem, PTHEME_STYLE pStyles, PTHEME_STYLE pActiveStyle)
51 {
52 int iListIndex;
53 HWND hwndList = GetDlgItem(hwndDlg, nIDDlgItem);
54 PTHEME_STYLE pCurrentStyle;
55
56 SendMessage(hwndList, CB_RESETCONTENT , 0, 0);
57
58 for (pCurrentStyle = pStyles;
59 pCurrentStyle;
60 pCurrentStyle = pCurrentStyle->NextStyle)
61 {
62 iListIndex = SendMessage(hwndList, CB_ADDSTRING, 0, (LPARAM)pCurrentStyle->DisplayName);
63 SendMessage(hwndList, CB_SETITEMDATA, iListIndex, (LPARAM)pCurrentStyle);
64 if (pCurrentStyle == pActiveStyle)
65 {
66 SendMessage(hwndList, CB_SETCURSEL, (WPARAM)iListIndex, 0);
67 }
68 }
69 }
70
71 static void
AppearancePage_ShowColorSchemes(HWND hwndDlg,GLOBALS * g)72 AppearancePage_ShowColorSchemes(HWND hwndDlg, GLOBALS *g)
73 {
74 AppearancePage_ShowStyles(hwndDlg,
75 IDC_APPEARANCE_COLORSCHEME,
76 g->ActiveTheme.Theme->ColoursList,
77 g->ActiveTheme.Color);
78 }
79
80 static void
AppearancePage_ShowSizes(HWND hwndDlg,GLOBALS * g)81 AppearancePage_ShowSizes(HWND hwndDlg, GLOBALS *g)
82 {
83 PTHEME_STYLE pSizes;
84
85 if (g->ActiveTheme.Theme->SizesList)
86 pSizes = g->ActiveTheme.Theme->SizesList;
87 else
88 pSizes = g->ActiveTheme.Color->ChildStyle;
89
90 AppearancePage_ShowStyles(hwndDlg,
91 IDC_APPEARANCE_SIZE,
92 pSizes,
93 g->ActiveTheme.Size);
94 }
95
96 static INT_PTR
AppearancePage_OnInit(HWND hwndDlg)97 AppearancePage_OnInit(HWND hwndDlg)
98 {
99 INT iListIndex;
100 HWND hwndTheme;
101 GLOBALS *g;
102 RECT rcPreview;
103 HDC hdcScreen;
104 PTHEME pTheme;
105
106 g = (GLOBALS*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBALS));
107 if (g == NULL)
108 return FALSE;
109
110 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)g);
111
112 g->bInitializing = TRUE;
113
114 if (!LoadCurrentScheme(&g->Scheme))
115 return FALSE;
116
117 g->pThemes = LoadThemes();
118 if (g->pThemes)
119 {
120 BOOL bLoadedTheme = FALSE;
121
122 if (g_GlobalData.pwszAction &&
123 g_GlobalData.pwszFile &&
124 wcscmp(g_GlobalData.pwszAction, L"OpenMSTheme") == 0)
125 {
126 bLoadedTheme = FindOrAppendTheme(g->pThemes,
127 g_GlobalData.pwszFile,
128 NULL,
129 NULL,
130 &g->ActiveTheme);
131 }
132
133 if (bLoadedTheme)
134 {
135 g->bThemeChanged = TRUE;
136 g->bSchemeChanged = TRUE;
137
138 PostMessageW(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0);
139
140 AppearancePage_LoadSelectedScheme(hwndDlg, g);
141 }
142 else
143 {
144 if (!GetActiveTheme(g->pThemes, &g->ActiveTheme))
145 {
146 g->ActiveTheme.ThemeActive = FALSE;
147 }
148 }
149
150 /*
151 * Keep a copy of the selected classic theme in order to select this
152 * when user selects the classic theme (and not a horrible random theme )
153 */
154 if (!GetActiveClassicTheme(g->pThemes, &g->ClassicTheme))
155 {
156 g->ClassicTheme.Theme = g->pThemes;
157 g->ClassicTheme.Color = g->pThemes->ColoursList;
158 g->ClassicTheme.Size = g->ClassicTheme.Color->ChildStyle;
159 }
160
161 if (g->ActiveTheme.ThemeActive == FALSE)
162 g->ActiveTheme = g->ClassicTheme;
163
164 GetClientRect(GetDlgItem(hwndDlg, IDC_APPEARANCE_PREVIEW), &rcPreview);
165
166 hdcScreen = GetDC(NULL);
167 g->hbmpThemePreview = CreateCompatibleBitmap(hdcScreen, rcPreview.right, rcPreview.bottom);
168 g->hdcThemePreview = CreateCompatibleDC(hdcScreen);
169 SelectObject(g->hdcThemePreview, g->hbmpThemePreview);
170 ReleaseDC(NULL, hdcScreen);
171
172 hwndTheme = GetDlgItem(hwndDlg, IDC_APPEARANCE_VISUAL_STYLE);
173
174 for (pTheme = g->pThemes; pTheme; pTheme = pTheme->NextTheme)
175 {
176 iListIndex = SendMessage(hwndTheme, CB_ADDSTRING, 0, (LPARAM)pTheme->DisplayName);
177 SendMessage(hwndTheme, CB_SETITEMDATA, iListIndex, (LPARAM)pTheme);
178 if (pTheme == g->ActiveTheme.Theme)
179 {
180 SendMessage(hwndTheme, CB_SETCURSEL, (WPARAM)iListIndex, 0);
181 }
182 }
183
184 if (g->ActiveTheme.Theme)
185 {
186 AppearancePage_ShowColorSchemes(hwndDlg, g);
187 AppearancePage_ShowSizes(hwndDlg, g);
188 AppearancePage_UpdateThemePreview(hwndDlg, g);
189 }
190 }
191 g->bInitializing = FALSE;
192
193 return FALSE;
194 }
195
196 static VOID
AppearancePage_OnDestroy(HWND hwndDlg,GLOBALS * g)197 AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g)
198 {
199 HeapFree(GetProcessHeap(), 0, g);
200 }
201
202 static PVOID
GetSelectedData(HWND hwndDlg,int nIDDlgItem)203 GetSelectedData(HWND hwndDlg, int nIDDlgItem)
204 {
205 HWND hwndCombo;
206 INT sel;
207
208 hwndCombo = GetDlgItem(hwndDlg, nIDDlgItem);
209 sel = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
210 if (sel == CB_ERR)
211 return NULL;
212 return (PVOID)SendMessage(hwndCombo, CB_GETITEMDATA, (WPARAM)sel, 0);
213 }
214
215 INT_PTR CALLBACK
AppearancePageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)216 AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
217 {
218 GLOBALS *g;
219 LPNMHDR lpnm;
220
221 g = (GLOBALS*)GetWindowLongPtr(hwndDlg, DWLP_USER);
222
223 switch (uMsg)
224 {
225 case WM_INITDIALOG:
226 return AppearancePage_OnInit(hwndDlg);
227
228 case WM_DESTROY:
229 AppearancePage_OnDestroy(hwndDlg, g);
230 break;
231
232 case WM_COMMAND:
233 if (g == NULL || g->bInitializing)
234 return FALSE;
235
236 switch (LOWORD(wParam))
237 {
238 case IDC_APPEARANCE_EFFECTS:
239 if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_EFFAPPEARANCE),
240 hwndDlg, EffAppearanceDlgProc, (LPARAM)g) == IDOK)
241 {
242 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
243 g->Scheme = g->SchemeAdv;
244 g->bSchemeChanged = TRUE;
245 }
246 break;
247
248 case IDC_APPEARANCE_ADVANCED:
249 if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_ADVAPPEARANCE),
250 hwndDlg, AdvAppearanceDlgProc, (LPARAM)g) == IDOK)
251 {
252 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
253 g->bSchemeChanged = TRUE;
254 g->Scheme = g->SchemeAdv;
255 g_GlobalData.desktop_color = g->Scheme.crColor[COLOR_DESKTOP];
256
257 AppearancePage_UpdateThemePreview(hwndDlg, g);
258 }
259 break;
260
261 case IDC_APPEARANCE_COLORSCHEME:
262 if (HIWORD(wParam) == CBN_SELCHANGE)
263 {
264 g->ActiveTheme.Color = (PTHEME_STYLE)GetSelectedData(hwndDlg, IDC_APPEARANCE_COLORSCHEME);
265 if (g->ActiveTheme.Color->ChildStyle != NULL)
266 g->ActiveTheme.Size = g->ActiveTheme.Color->ChildStyle;
267
268 g->bSchemeChanged = TRUE;
269 if (g->ActiveTheme.ThemeActive)
270 g->bThemeChanged = TRUE;
271
272 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
273
274 AppearancePage_LoadSelectedScheme(hwndDlg, g);
275 AppearancePage_ShowSizes(hwndDlg, g);
276 AppearancePage_UpdateThemePreview(hwndDlg, g);
277 }
278 break;
279
280 case IDC_APPEARANCE_VISUAL_STYLE:
281 if (HIWORD(wParam) == CBN_SELCHANGE)
282 {
283 PTHEME pTheme = (PTHEME)GetSelectedData(hwndDlg, IDC_APPEARANCE_VISUAL_STYLE);
284
285 if (g->ClassicTheme.Theme == pTheme)
286 g->ActiveTheme = g->ClassicTheme;
287 else
288 {
289 g->ActiveTheme.Theme = pTheme;
290 g->ActiveTheme.Size = pTheme->SizesList;
291 g->ActiveTheme.Color = pTheme->ColoursList;
292 g->ActiveTheme.ThemeActive = TRUE;
293 }
294
295 g->bThemeChanged = TRUE;
296 g->bSchemeChanged = TRUE;
297
298 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
299
300 AppearancePage_ShowColorSchemes(hwndDlg, g);
301 AppearancePage_ShowSizes(hwndDlg, g);
302 AppearancePage_LoadSelectedScheme(hwndDlg, g);
303 AppearancePage_UpdateThemePreview(hwndDlg, g);
304 }
305 break;
306
307 case IDC_APPEARANCE_SIZE:
308 if (HIWORD(wParam) == CBN_SELCHANGE)
309 {
310 g->ActiveTheme.Size = (PTHEME_STYLE)GetSelectedData(hwndDlg, IDC_APPEARANCE_SIZE);
311 g->bSchemeChanged = TRUE;
312 if (g->ActiveTheme.ThemeActive)
313 g->bThemeChanged = TRUE;
314
315 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
316
317 AppearancePage_LoadSelectedScheme(hwndDlg, g);
318 AppearancePage_UpdateThemePreview(hwndDlg, g);
319 }
320 }
321 break;
322
323 case WM_NOTIFY:
324 lpnm = (LPNMHDR)lParam;
325 switch (lpnm->code)
326 {
327 case PSN_APPLY:
328
329 if (g->bThemeChanged)
330 {
331 ActivateTheme(&g->ActiveTheme);
332 }
333
334 if (g->bSchemeChanged)
335 {
336 ApplyScheme(&g->Scheme, &g->ActiveTheme);
337 if (g->ActiveTheme.ThemeActive == FALSE)
338 g->ClassicTheme = g->ActiveTheme;
339 }
340
341 AppearancePage_UpdateThemePreview(hwndDlg, g);
342 g->bThemeChanged = FALSE;
343 g->bSchemeChanged = FALSE;
344 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)PSNRET_NOERROR);
345 return TRUE;
346
347 case PSN_KILLACTIVE:
348 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)FALSE);
349 return TRUE;
350
351 case PSN_SETACTIVE:
352 if (g->Scheme.crColor[COLOR_DESKTOP] != g_GlobalData.desktop_color)
353 {
354 g->Scheme.crColor[COLOR_DESKTOP] = g_GlobalData.desktop_color;
355 AppearancePage_UpdateThemePreview(hwndDlg, g);
356 }
357 break;
358 }
359 break;
360 }
361
362 return FALSE;
363 }
364