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 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 197 AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g) 198 { 199 HeapFree(GetProcessHeap(), 0, g); 200 } 201 202 static PVOID 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 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