xref: /reactos/dll/cpl/desk/appearance.c (revision 9393fc32)
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