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 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 hwndTheme = GetDlgItem(hwndDlg, IDC_APPEARANCE_VISUAL_STYLE); 146 147 for (pTheme = g->pThemes; pTheme; pTheme = pTheme->NextTheme) 148 { 149 iListIndex = SendMessage(hwndTheme, CB_ADDSTRING, 0, (LPARAM)pTheme->DisplayName); 150 SendMessage(hwndTheme, CB_SETITEMDATA, iListIndex, (LPARAM)pTheme); 151 if (pTheme == g->ActiveTheme.Theme) 152 { 153 SendMessage(hwndTheme, CB_SETCURSEL, (WPARAM)iListIndex, 0); 154 } 155 } 156 157 if (g->ActiveTheme.Theme) 158 { 159 AppearancePage_ShowColorSchemes(hwndDlg, g); 160 AppearancePage_ShowSizes(hwndDlg, g); 161 AppearancePage_UpdateThemePreview(hwndDlg, g); 162 } 163 } 164 g->bInitializing = FALSE; 165 166 return FALSE; 167 } 168 169 static VOID 170 AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g) 171 { 172 HeapFree(GetProcessHeap(), 0, g); 173 } 174 175 static PVOID 176 GetSelectedData(HWND hwndDlg, int nIDDlgItem) 177 { 178 HWND hwndCombo; 179 INT sel; 180 181 hwndCombo = GetDlgItem(hwndDlg, nIDDlgItem); 182 sel = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0); 183 if (sel == CB_ERR) 184 return NULL; 185 return (PVOID)SendMessage(hwndCombo, CB_GETITEMDATA, (WPARAM)sel, 0); 186 } 187 188 INT_PTR CALLBACK 189 AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 190 { 191 GLOBALS *g; 192 LPNMHDR lpnm; 193 194 g = (GLOBALS*)GetWindowLongPtr(hwndDlg, DWLP_USER); 195 196 switch (uMsg) 197 { 198 case WM_INITDIALOG: 199 return AppearancePage_OnInit(hwndDlg); 200 201 case WM_DESTROY: 202 AppearancePage_OnDestroy(hwndDlg, g); 203 break; 204 205 case WM_COMMAND: 206 if(g == NULL || g->bInitializing) 207 return FALSE; 208 209 switch (LOWORD(wParam)) 210 { 211 case IDC_APPEARANCE_EFFECTS: 212 if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_EFFAPPEARANCE), 213 hwndDlg, EffAppearanceDlgProc, (LPARAM)g) == IDOK) 214 { 215 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 216 g->Scheme = g->SchemeAdv; 217 g->bSchemeChanged = TRUE; 218 } 219 break; 220 221 case IDC_APPEARANCE_ADVANCED: 222 if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_ADVAPPEARANCE), 223 hwndDlg, AdvAppearanceDlgProc, (LPARAM)g) == IDOK) 224 { 225 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 226 g->bSchemeChanged = TRUE; 227 g->Scheme = g->SchemeAdv; 228 g_GlobalData.desktop_color = g->Scheme.crColor[COLOR_DESKTOP]; 229 230 AppearancePage_UpdateThemePreview(hwndDlg, g); 231 } 232 break; 233 234 case IDC_APPEARANCE_COLORSCHEME: 235 if (HIWORD(wParam) == CBN_SELCHANGE) 236 { 237 g->ActiveTheme.Color = (PTHEME_STYLE)GetSelectedData(hwndDlg, IDC_APPEARANCE_COLORSCHEME); 238 if (g->ActiveTheme.Color->ChildStyle != NULL) 239 g->ActiveTheme.Size = g->ActiveTheme.Color->ChildStyle; 240 241 g->bSchemeChanged = TRUE; 242 if (g->ActiveTheme.ThemeActive) 243 g->bThemeChanged = TRUE; 244 245 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 246 247 AppearancePage_LoadSelectedScheme(hwndDlg, g); 248 AppearancePage_ShowSizes(hwndDlg, g); 249 AppearancePage_UpdateThemePreview(hwndDlg, g); 250 } 251 break; 252 253 case IDC_APPEARANCE_VISUAL_STYLE: 254 if (HIWORD(wParam) == CBN_SELCHANGE) 255 { 256 PTHEME pTheme = (PTHEME)GetSelectedData(hwndDlg, IDC_APPEARANCE_VISUAL_STYLE); 257 258 if (g->ClassicTheme.Theme == pTheme) 259 g->ActiveTheme = g->ClassicTheme; 260 else 261 { 262 g->ActiveTheme.Theme = pTheme; 263 g->ActiveTheme.Size = pTheme->SizesList; 264 g->ActiveTheme.Color = pTheme->ColoursList; 265 g->ActiveTheme.ThemeActive = TRUE; 266 } 267 268 g->bThemeChanged = TRUE; 269 g->bSchemeChanged = TRUE; 270 271 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 272 273 AppearancePage_ShowColorSchemes(hwndDlg, g); 274 AppearancePage_ShowSizes(hwndDlg, g); 275 AppearancePage_LoadSelectedScheme(hwndDlg, g); 276 AppearancePage_UpdateThemePreview(hwndDlg, g); 277 } 278 break; 279 280 case IDC_APPEARANCE_SIZE: 281 if (HIWORD(wParam) == CBN_SELCHANGE) 282 { 283 g->ActiveTheme.Size = (PTHEME_STYLE)GetSelectedData(hwndDlg, IDC_APPEARANCE_SIZE); 284 g->bSchemeChanged = TRUE; 285 if(g->ActiveTheme.ThemeActive) 286 g->bThemeChanged = TRUE; 287 288 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 289 290 AppearancePage_LoadSelectedScheme(hwndDlg, g); 291 AppearancePage_UpdateThemePreview(hwndDlg, g); 292 } 293 } 294 break; 295 296 case WM_NOTIFY: 297 lpnm = (LPNMHDR)lParam; 298 switch (lpnm->code) 299 { 300 case PSN_APPLY: 301 302 if (g->bThemeChanged) 303 { 304 ActivateTheme(&g->ActiveTheme); 305 } 306 307 if (g->bSchemeChanged) 308 { 309 ApplyScheme(&g->Scheme, &g->ActiveTheme); 310 if (g->ActiveTheme.ThemeActive == FALSE) 311 g->ClassicTheme = g->ActiveTheme; 312 } 313 314 AppearancePage_UpdateThemePreview(hwndDlg, g); 315 g->bThemeChanged = FALSE; 316 g->bSchemeChanged = FALSE; 317 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)PSNRET_NOERROR); 318 return TRUE; 319 320 case PSN_KILLACTIVE: 321 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)FALSE); 322 return TRUE; 323 324 case PSN_SETACTIVE: 325 if (g->Scheme.crColor[COLOR_DESKTOP] != g_GlobalData.desktop_color) 326 { 327 g->Scheme.crColor[COLOR_DESKTOP] = g_GlobalData.desktop_color; 328 AppearancePage_UpdateThemePreview(hwndDlg, g); 329 } 330 break; 331 } 332 break; 333 } 334 335 return FALSE; 336 } 337