Create a branch for Aleksandar Andrejevic for his work on NTVDM. See http://jira...
[reactos.git] / dll / cpl / desk / appearance.c
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
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
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
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
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
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
97 AppearancePage_OnInit(HWND hwndDlg)
98 {
99 INT iListIndex;
100 HWND hwndColor, 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 if (!GetActiveTheme(g->pThemes, &g->ActiveTheme))
121 g->ActiveTheme.ThemeActive = FALSE;
122
123 /*
124 * Keep a copy of the selected classic theme in order to select this
125 * when user selects the classic theme (and not a horrible random theme )
126 */
127 if (!GetActiveClassicTheme(g->pThemes, &g->ClassicTheme))
128 {
129 g->ClassicTheme.Theme = g->pThemes;
130 g->ClassicTheme.Color = g->pThemes->ColoursList;
131 g->ClassicTheme.Size = g->ClassicTheme.Color->ChildStyle;
132 }
133
134 if (g->ActiveTheme.ThemeActive == FALSE)
135 g->ActiveTheme = g->ClassicTheme;
136
137 GetClientRect(GetDlgItem(hwndDlg, IDC_APPEARANCE_PREVIEW), &rcPreview);
138
139 hdcScreen = GetDC(NULL);
140 g->hbmpThemePreview = CreateCompatibleBitmap(hdcScreen, rcPreview.right, rcPreview.bottom);
141 g->hdcThemePreview = CreateCompatibleDC(hdcScreen);
142 SelectObject(g->hdcThemePreview, g->hbmpThemePreview);
143 ReleaseDC(NULL, hdcScreen);
144
145 hwndColor = GetDlgItem(hwndDlg, IDC_APPEARANCE_COLORSCHEME);
146 hwndTheme = GetDlgItem(hwndDlg, IDC_APPEARANCE_VISUAL_STYLE);
147
148 for (pTheme = g->pThemes; pTheme; pTheme = pTheme->NextTheme)
149 {
150 iListIndex = SendMessage(hwndTheme, CB_ADDSTRING, 0, (LPARAM)pTheme->DisplayName);
151 SendMessage(hwndTheme, CB_SETITEMDATA, iListIndex, (LPARAM)pTheme);
152 if (pTheme == g->ActiveTheme.Theme)
153 {
154 SendMessage(hwndTheme, CB_SETCURSEL, (WPARAM)iListIndex, 0);
155 }
156 }
157
158 if (g->ActiveTheme.Theme)
159 {
160 AppearancePage_ShowColorSchemes(hwndDlg, g);
161 AppearancePage_ShowSizes(hwndDlg, g);
162 AppearancePage_UpdateThemePreview(hwndDlg, g);
163 }
164 }
165 g->bInitializing = FALSE;
166
167 return FALSE;
168 }
169
170 static VOID
171 AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g)
172 {
173 HeapFree(GetProcessHeap(), 0, g);
174 }
175
176 static PVOID
177 GetSelectedData(HWND hwndDlg, int nIDDlgItem)
178 {
179 HWND hwndCombo;
180 INT sel;
181
182 hwndCombo = GetDlgItem(hwndDlg, nIDDlgItem);
183 sel = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
184 if (sel == CB_ERR)
185 return NULL;
186 return (PVOID)SendMessage(hwndCombo, CB_GETITEMDATA, (WPARAM)sel, 0);
187 }
188
189 INT_PTR CALLBACK
190 AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
191 {
192 GLOBALS *g;
193 LPNMHDR lpnm;
194
195 g = (GLOBALS*)GetWindowLongPtr(hwndDlg, DWLP_USER);
196
197 switch (uMsg)
198 {
199 case WM_INITDIALOG:
200 return AppearancePage_OnInit(hwndDlg);
201
202 case WM_DESTROY:
203 AppearancePage_OnDestroy(hwndDlg, g);
204 break;
205
206 case WM_COMMAND:
207 if(g == NULL || g->bInitializing)
208 return FALSE;
209
210 switch (LOWORD(wParam))
211 {
212 case IDC_APPEARANCE_EFFECTS:
213 if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_EFFAPPEARANCE),
214 hwndDlg, EffAppearanceDlgProc, (LPARAM)g) == IDOK)
215 {
216 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
217 g->Scheme = g->SchemeAdv;
218 g->bSchemeChanged = TRUE;
219 }
220 break;
221
222 case IDC_APPEARANCE_ADVANCED:
223 if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_ADVAPPEARANCE),
224 hwndDlg, AdvAppearanceDlgProc, (LPARAM)g) == IDOK)
225 {
226 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
227 g->bSchemeChanged = TRUE;
228 g->Scheme = g->SchemeAdv;
229 g_GlobalData.desktop_color = g->Scheme.crColor[COLOR_DESKTOP];
230
231 AppearancePage_UpdateThemePreview(hwndDlg, g);
232 }
233 break;
234
235 case IDC_APPEARANCE_COLORSCHEME:
236 if (HIWORD(wParam) == CBN_SELCHANGE)
237 {
238 g->ActiveTheme.Color = (PTHEME_STYLE)GetSelectedData(hwndDlg, IDC_APPEARANCE_COLORSCHEME);
239 if (g->ActiveTheme.Color->ChildStyle != NULL)
240 g->ActiveTheme.Size = g->ActiveTheme.Color->ChildStyle;
241
242 g->bSchemeChanged = TRUE;
243 if (g->ActiveTheme.ThemeActive)
244 g->bThemeChanged = TRUE;
245
246 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
247
248 AppearancePage_LoadSelectedScheme(hwndDlg, g);
249 AppearancePage_ShowSizes(hwndDlg, g);
250 AppearancePage_UpdateThemePreview(hwndDlg, g);
251 }
252 break;
253
254 case IDC_APPEARANCE_VISUAL_STYLE:
255 if (HIWORD(wParam) == CBN_SELCHANGE)
256 {
257 PTHEME pTheme = (PTHEME)GetSelectedData(hwndDlg, IDC_APPEARANCE_VISUAL_STYLE);
258
259 if (g->ClassicTheme.Theme == pTheme)
260 g->ActiveTheme = g->ClassicTheme;
261 else
262 {
263 g->ActiveTheme.Theme = pTheme;
264 g->ActiveTheme.Size = pTheme->SizesList;
265 g->ActiveTheme.Color = pTheme->ColoursList;
266 g->ActiveTheme.ThemeActive = TRUE;
267 }
268
269 g->bThemeChanged = TRUE;
270 g->bSchemeChanged = TRUE;
271
272 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
273
274 AppearancePage_ShowColorSchemes(hwndDlg, g);
275 AppearancePage_ShowSizes(hwndDlg, g);
276 AppearancePage_LoadSelectedScheme(hwndDlg, g);
277 AppearancePage_UpdateThemePreview(hwndDlg, g);
278 }
279 break;
280
281 case IDC_APPEARANCE_SIZE:
282 if (HIWORD(wParam) == CBN_SELCHANGE)
283 {
284 g->ActiveTheme.Size = (PTHEME_STYLE)GetSelectedData(hwndDlg, IDC_APPEARANCE_SIZE);
285 g->bSchemeChanged = TRUE;
286 if(g->ActiveTheme.ThemeActive)
287 g->bThemeChanged = TRUE;
288
289 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
290
291 AppearancePage_LoadSelectedScheme(hwndDlg, g);
292 AppearancePage_UpdateThemePreview(hwndDlg, g);
293 }
294 }
295 break;
296
297 case WM_NOTIFY:
298 lpnm = (LPNMHDR)lParam;
299 switch (lpnm->code)
300 {
301 case PSN_APPLY:
302
303 if (g->bThemeChanged)
304 {
305 ActivateTheme(&g->ActiveTheme);
306 }
307
308 if (g->bSchemeChanged)
309 {
310 ApplyScheme(&g->Scheme, &g->ActiveTheme);
311 if (g->ActiveTheme.ThemeActive == FALSE)
312 g->ClassicTheme = g->ActiveTheme;
313 }
314
315 AppearancePage_UpdateThemePreview(hwndDlg, g);
316 g->bThemeChanged = FALSE;
317 g->bSchemeChanged = FALSE;
318 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)PSNRET_NOERROR);
319 return TRUE;
320
321 case PSN_KILLACTIVE:
322 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)FALSE);
323 return TRUE;
324
325 case PSN_SETACTIVE:
326 if (g->Scheme.crColor[COLOR_DESKTOP] != g_GlobalData.desktop_color)
327 {
328 g->Scheme.crColor[COLOR_DESKTOP] = g_GlobalData.desktop_color;
329 AppearancePage_UpdateThemePreview(hwndDlg, g);
330 }
331 break;
332 }
333 break;
334 }
335
336 return FALSE;
337 }