1 /* $Id$ 2 * 3 * COPYRIGHT: See COPYING in the top level directory 4 * PROJECT: ReactOS Display Control Panel 5 * FILE: lib/cpl/desk/appearance.c 6 * PURPOSE: Appearance property page 7 * 8 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com) 9 * Timo Kreuzer (timo[dot]kreuzer[at]web[dot]de 10 */ 11 12 #include "desk.h" 13 #include "appearance.h" 14 15 /******************************************************************************/ 16 17 /* This const assigns the color and metric numbers to the elements from the elements list */ 18 19 /* Size 1 (width) Size 2 (height) Color 1 Color 2 Font Fontcolor */ 20 const ASSIGNMENT g_Assignment[NUM_ELEMENTS] = 21 { {-1, -1, COLOR_DESKTOP, -1, -1, -1}, /* -Desktop */ 22 {SIZE_CAPTION_Y, -1, COLOR_INACTIVECAPTION, COLOR_GRADIENTINACTIVECAPTION, FONT_CAPTION, -1}, /* inactive window caption */ 23 {SIZE_BORDER_X, SIZE_BORDER_Y, COLOR_INACTIVEBORDER, -1, -1, -1}, /* inactive window border */ 24 {SIZE_CAPTION_Y, -1, COLOR_ACTIVECAPTION, COLOR_GRADIENTACTIVECAPTION, FONT_CAPTION, COLOR_CAPTIONTEXT}, /* -active window caption */ 25 {SIZE_BORDER_X, SIZE_BORDER_Y, COLOR_ACTIVEBORDER, -1, -1, -1}, /* active window border */ 26 {SIZE_MENU_X, SIZE_MENU_Y, COLOR_MENU, -1, FONT_MENU, COLOR_MENUTEXT}, /* menu */ 27 {SIZE_MENU_X, SIZE_MENU_Y, COLOR_HIGHLIGHT, -1, FONT_HILIGHT, COLOR_HIGHLIGHTTEXT},/* marked element */ 28 {-1, -1, COLOR_WINDOW, -1 /*COLOR_WINDOWFRAME*/, -1, COLOR_WINDOWTEXT}, /* window */ 29 {SIZE_SCROLL_X, SIZE_SCROLL_Y, COLOR_SCROLLBAR, -1, -1, -1}, /* scroll bar */ 30 {-1, -1, COLOR_3DFACE, -1, -1, COLOR_BTNTEXT}, /* 3d objects */ 31 {SIZE_SMCAPTION_Y,-1, -1, -1, FONT_SMCAPTION, -1}, /* palette window caption */ 32 {-1, -1, -1, -1, -1, -1}, /* symbol caption FIXME: Access? */ 33 {SIZE_CAPTION_Y, -1, -1, -1, -1, -1}, /* caption bar */ 34 {-1, -1, -1, -1, -1, COLOR_GRAYTEXT}, /* inactive menu item FIXME: Access? */ 35 {-1, -1, -1, -1, FONT_DIALOG, COLOR_WINDOWTEXT}, /* dialog */ 36 {-1, -1, -1, -1, -1, -1}, /* scrollbar controls FIXME: Access? */ 37 {-1, -1, COLOR_APPWORKSPACE, -1, -1, -1}, /* application background */ 38 {-1, -1, -1, -1, -1, -1}, /* small caption bar FIXME: Access? */ 39 {SIZE_ICON_SPC_X, -1, -1, -1, -1, -1}, /* symbol distance horiz. */ 40 {SIZE_ICON_SPC_Y, -1, -1, -1, -1, -1}, /* symbol distance vert. */ 41 {-1, -1, COLOR_INFOBK, -1, FONT_INFO, COLOR_INFOTEXT}, /* quickinfo */ 42 {SIZE_ICON_X, SIZE_ICON_Y, -1, -1, FONT_ICON, -1}}; /* symbol */ 43 44 /* This is the list of names for the colors stored in the registry */ 45 const TCHAR g_RegColorNames[NUM_COLORS][MAX_COLORNAMELENGTH] = 46 {TEXT("Scrollbar"), /* 00 = COLOR_SCROLLBAR */ 47 TEXT("Background"), /* 01 = COLOR_DESKTOP */ 48 TEXT("ActiveTitle"), /* 02 = COLOR_ACTIVECAPTION */ 49 TEXT("InactiveTitle"), /* 03 = COLOR_INACTIVECAPTION */ 50 TEXT("Menu"), /* 04 = COLOR_MENU */ 51 TEXT("Window"), /* 05 = COLOR_WINDOW */ 52 TEXT("WindowFrame"), /* 06 = COLOR_WINDOWFRAME */ 53 TEXT("MenuText"), /* 07 = COLOR_MENUTEXT */ 54 TEXT("WindowText"), /* 08 = COLOR_WINDOWTEXT */ 55 TEXT("TitleText"), /* 09 = COLOR_CAPTIONTEXT */ 56 TEXT("ActiveBorder"), /* 10 = COLOR_ACTIVEBORDER */ 57 TEXT("InactiveBorder"), /* 11 = COLOR_INACTIVEBORDER */ 58 TEXT("AppWorkSpace"), /* 12 = COLOR_APPWORKSPACE */ 59 TEXT("Hilight"), /* 13 = COLOR_HIGHLIGHT */ 60 TEXT("HilightText"), /* 14 = COLOR_HIGHLIGHTTEXT */ 61 TEXT("ButtonFace"), /* 15 = COLOR_BTNFACE */ 62 TEXT("ButtonShadow"), /* 16 = COLOR_BTNSHADOW */ 63 TEXT("GrayText"), /* 17 = COLOR_GRAYTEXT */ 64 TEXT("ButtonText"), /* 18 = COLOR_BTNTEXT */ 65 TEXT("InactiveTitleText"), /* 19 = COLOR_INACTIVECAPTIONTEXT */ 66 TEXT("ButtonHilight"), /* 20 = COLOR_BTNHIGHLIGHT */ 67 TEXT("ButtonDkShadow"), /* 21 = COLOR_3DDKSHADOW */ 68 TEXT("ButtonLight"), /* 22 = COLOR_3DLIGHT */ 69 TEXT("InfoText"), /* 23 = COLOR_INFOTEXT */ 70 TEXT("InfoWindow"), /* 24 = COLOR_INFOBK */ 71 TEXT("ButtonAlternateFace"), /* 25 = COLOR_ALTERNATEBTNFACE */ 72 TEXT("HotTrackingColor"), /* 26 = COLOR_HOTLIGHT */ 73 TEXT("GradientActiveTitle"), /* 27 = COLOR_GRADIENTACTIVECAPTION */ 74 TEXT("GradientInactiveTitle"), /* 28 = COLOR_GRADIENTINACTIVECAPTION */ 75 TEXT("MenuHilight"), /* 29 = COLOR_MENUHILIGHT */ 76 TEXT("MenuBar"), /* 30 = COLOR_MENUBAR */ 77 }; 78 79 /* This is the list of used metrics and their numbers */ 80 const int g_SizeMetric[NUM_SIZES] = 81 { 82 SM_CXBORDER, 83 SM_CYBORDER, 84 SM_CYCAPTION, 85 SM_CXICON, 86 SM_CYICON, 87 SM_CXICONSPACING, 88 SM_CYICONSPACING, 89 SM_CXMENUSIZE, 90 SM_CYMENU, 91 SM_CXVSCROLL, 92 SM_CYHSCROLL, 93 SM_CYSMCAPTION 94 }; 95 96 /******************************************************************************/ 97 98 static VOID 99 LoadCurrentTheme(GLOBALS* g) 100 { 101 INT i; 102 NONCLIENTMETRICS NonClientMetrics; 103 104 g->Theme.bHasChanged = FALSE; 105 /* FIXME: it may be custom! */ 106 g->Theme.bIsCustom = FALSE; 107 108 /* Load colors */ 109 for (i = 0; i <= 30; i++) 110 { 111 g->ColorList[i] = i; 112 g->Theme.crColor[i] = (COLORREF)GetSysColor(i); 113 } 114 115 /* Load sizes */ 116 for (i = 0; i <= 11; i++) 117 { 118 g->Theme.Size[i] = GetSystemMetrics(g_SizeMetric[i]); 119 } 120 121 /* Load fonts */ 122 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS); 123 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0); 124 g->Theme.lfFont[FONT_CAPTION] = NonClientMetrics.lfCaptionFont; 125 g->Theme.lfFont[FONT_SMCAPTION] = NonClientMetrics.lfSmCaptionFont; 126 g->Theme.lfFont[FONT_MENU] = NonClientMetrics.lfMenuFont; 127 g->Theme.lfFont[FONT_INFO] = NonClientMetrics.lfStatusFont; 128 g->Theme.lfFont[FONT_DIALOG] = NonClientMetrics.lfMessageFont; 129 SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &g->Theme.lfFont[FONT_ICON], 0); 130 131 /* Effects */ 132 /* "Use the following transition effect for menus and tooltips" */ 133 SystemParametersInfo(SPI_GETMENUANIMATION, sizeof(BOOL), &g->Theme.Effects.bMenuAnimation, 0); 134 SystemParametersInfo(SPI_GETMENUFADE, sizeof(BOOL), &g->Theme.Effects.bMenuFade, 0); 135 /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings 136 * Just keep them in sync for now: 137 */ 138 g->Theme.Effects.bTooltipAnimation = g->Theme.Effects.bMenuAnimation; 139 g->Theme.Effects.bTooltipFade = g->Theme.Effects.bMenuFade; 140 141 /* show content of windows during dragging */ 142 //SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, g->Theme.Effects.bDragFullWindows, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 143 SystemParametersInfoW(SPI_GETDRAGFULLWINDOWS, 0, &g->Theme.Effects.bDragFullWindows, 0); 144 145 /* "Hide underlined letters for keyboard navigation until I press the Alt key" */ 146 SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &g->Theme.Effects.bKeyboardCues, 0); 147 } 148 149 150 static BOOL 151 LoadThemeFromReg(GLOBALS* g) 152 { 153 INT i; 154 TCHAR strSizeName[20] = {TEXT("Sizes\\0")}; 155 TCHAR strValueName[10]; 156 HKEY hkNewSchemes, hkScheme, hkSize; 157 DWORD dwType, dwLength; 158 BOOL Ret = FALSE; 159 INT iPreset = g->Theme.Id; 160 161 if(RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"), 162 0, KEY_READ, &hkNewSchemes) == ERROR_SUCCESS) 163 { 164 if(RegOpenKeyEx(hkNewSchemes, g->ThemeTemplates[iPreset].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS) 165 { 166 lstrcpyn(&strSizeName[6],g->ThemeTemplates[iPreset].strSizeName, 3); 167 if(RegOpenKeyEx(hkScheme, strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS) 168 { 169 Ret = TRUE; 170 171 dwLength = sizeof(DWORD); 172 if (RegQueryValueEx(hkSize, TEXT("FlatMenus"), NULL, &dwType, (LPBYTE)&g->Theme.bFlatMenus, &dwLength) != ERROR_SUCCESS || 173 dwType != REG_DWORD || dwLength != sizeof(DWORD)) 174 { 175 /* Failed to read registry value */ 176 g->Theme.bFlatMenus = FALSE; 177 Ret = FALSE; 178 } 179 180 for (i = 0; i <= 30; i++) 181 { 182 wsprintf(strValueName, TEXT("Color #%d"), i); 183 dwLength = sizeof(COLORREF); 184 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&g->Theme.crColor[i], &dwLength) != ERROR_SUCCESS || 185 dwType != REG_DWORD || dwLength != sizeof(COLORREF)) 186 { 187 /* Failed to read registry value, initialize with current setting for now */ 188 g->Theme.crColor[i] = GetSysColor(i); 189 Ret = FALSE; 190 } 191 } 192 for (i = 0; i <= 5; i++) 193 { 194 wsprintf(strValueName, TEXT("Font #%d"), i); 195 dwLength = sizeof(LOGFONT); 196 g->Theme.lfFont[i].lfFaceName[0] = 'x'; 197 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&g->Theme.lfFont[i], &dwLength) != ERROR_SUCCESS || 198 dwType != REG_BINARY || dwLength != sizeof(LOGFONT)) 199 { 200 /* Failed to read registry value */ 201 Ret = FALSE; 202 } 203 } 204 for (i = 0; i <= 8; i++) 205 { 206 wsprintf(strValueName, TEXT("Size #%d"), i); 207 dwLength = sizeof(UINT64); 208 if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&g->Theme.Size[i], &dwLength) != ERROR_SUCCESS || 209 dwType != REG_QWORD || dwLength != sizeof(UINT64)) 210 { 211 /* Failed to read registry value, initialize with current setting for now */ 212 g->Theme.Size[i] = GetSystemMetrics(g_SizeMetric[i]); 213 Ret = FALSE; 214 } 215 } 216 RegCloseKey(hkScheme); 217 } 218 RegCloseKey(hkScheme); 219 } 220 RegCloseKey(hkNewSchemes); 221 } 222 223 return Ret; 224 } 225 226 static VOID 227 _UpdateUserPref(UINT SpiGet,UINT SpiSet,BOOL *pbFlag) 228 { 229 SystemParametersInfo(SpiSet, 0, (PVOID)pbFlag, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 230 } 231 #define UPDATE_USERPREF(NAME,pbFlag) _UpdateUserPref(SPI_GET ## NAME, SPI_SET ## NAME, pbFlag) 232 233 static VOID 234 ApplyTheme(GLOBALS* g) 235 { 236 INT i, Result; 237 HKEY hKey; 238 DWORD dwDisposition = 0; 239 TCHAR clText[16] = {0}; 240 NONCLIENTMETRICS NonClientMetrics; 241 HFONT hMyFont; 242 LOGFONT lfButtonFont; 243 244 if (!g->Theme.bHasChanged) 245 return; 246 247 /* Update some globals */ 248 g->crCOLOR_BTNFACE = g->Theme.crColor[COLOR_BTNFACE]; 249 g->crCOLOR_BTNTEXT = g->Theme.crColor[COLOR_BTNTEXT]; 250 g->crCOLOR_BTNSHADOW = g->Theme.crColor[COLOR_BTNSHADOW]; 251 g->crCOLOR_BTNHIGHLIGHT = g->Theme.crColor[COLOR_BTNHIGHLIGHT]; 252 lfButtonFont = g->Theme.lfFont[FONT_DIALOG]; 253 254 /* Create new font for bold button */ 255 lfButtonFont.lfWeight = FW_BOLD; 256 lfButtonFont.lfItalic = FALSE; 257 hMyFont = CreateFontIndirect(&lfButtonFont); 258 if (hMyFont) 259 { 260 if (g->hBoldFont) 261 DeleteObject(g->hBoldFont); 262 g->hBoldFont = hMyFont; 263 } 264 265 /* Create new font for italic button */ 266 lfButtonFont.lfWeight = FW_REGULAR; 267 lfButtonFont.lfItalic = TRUE; 268 hMyFont = CreateFontIndirect(&lfButtonFont); 269 if (hMyFont) 270 { 271 if (g->hItalicFont) 272 DeleteObject(g->hItalicFont); 273 g->hItalicFont = hMyFont; 274 } 275 276 /* Apply Colors from global variable */ 277 SetSysColors(30, &g->ColorList[0], &g->Theme.crColor[0]); 278 279 /* Save colors to registry */ 280 Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, KEY_ALL_ACCESS, &hKey); 281 if (Result != ERROR_SUCCESS) 282 { 283 /* Could not open the key, try to create it */ 284 Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,&hKey, &dwDisposition); 285 } 286 287 if (Result == ERROR_SUCCESS) 288 { 289 for (i = 0; i <= 30; i++) 290 { 291 DWORD red = GetRValue(g->Theme.crColor[i]); 292 DWORD green = GetGValue(g->Theme.crColor[i]); 293 DWORD blue = GetBValue(g->Theme.crColor[i]); 294 wsprintf(clText, TEXT("%d %d %d"), red, green, blue); 295 RegSetValueEx(hKey, g_RegColorNames[i], 0, REG_SZ, (BYTE *)clText, lstrlen( clText )*sizeof(TCHAR) + sizeof(TCHAR)); 296 } 297 298 RegCloseKey(hKey); 299 } 300 301 /* Apply the fonts */ 302 NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS); 303 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0); 304 NonClientMetrics.lfCaptionFont = g->Theme.lfFont[FONT_CAPTION]; 305 NonClientMetrics.lfSmCaptionFont = g->Theme.lfFont[FONT_SMCAPTION]; 306 NonClientMetrics.lfMenuFont = g->Theme.lfFont[FONT_MENU]; 307 NonClientMetrics.lfStatusFont = g->Theme.lfFont[FONT_INFO]; 308 NonClientMetrics.lfMessageFont = g->Theme.lfFont[FONT_DIALOG]; 309 SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0); 310 SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(LOGFONT), &g->Theme.lfFont[FONT_ICON], 0); 311 312 /* FIXME: Apply size metrics */ 313 314 /* Save fonts and size metrics to registry */ 315 Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, KEY_ALL_ACCESS, &hKey); 316 if (Result != ERROR_SUCCESS) 317 { 318 /* Could not open the key, try to create it */ 319 Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,&hKey, &dwDisposition); 320 } 321 322 if (Result == ERROR_SUCCESS) 323 { 324 RegSetValueEx(hKey, TEXT("CaptionFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_CAPTION], sizeof(LOGFONT)); 325 RegSetValueEx(hKey, TEXT("SmCaptionFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_SMCAPTION], sizeof(LOGFONT)); 326 RegSetValueEx(hKey, TEXT("IconFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_ICON], sizeof(LOGFONT)); 327 RegSetValueEx(hKey, TEXT("MenuFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_MENU], sizeof(LOGFONT)); 328 RegSetValueEx(hKey, TEXT("StatusFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_INFO], sizeof(LOGFONT)); 329 RegSetValueEx(hKey, TEXT("MessageFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_DIALOG], sizeof(LOGFONT)); 330 331 /* Save size metrics to registry */ 332 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_BORDER_X]); 333 RegSetValueEx(hKey, TEXT("BorderWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 334 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_CAPTION_Y]); 335 RegSetValueEx(hKey, TEXT("CaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 336 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_CAPTION_Y]); 337 RegSetValueEx(hKey, TEXT("CaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 338 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SMCAPTION_Y]); 339 RegSetValueEx(hKey, TEXT("SmCaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 340 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SMCAPTION_Y]); 341 RegSetValueEx(hKey, TEXT("SmCaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 342 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_ICON_SPC_X]); 343 RegSetValueEx(hKey, TEXT("IconSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 344 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_ICON_SPC_Y]); 345 RegSetValueEx(hKey, TEXT("IconVerticalSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 346 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_MENU_X]); 347 RegSetValueEx(hKey, TEXT("MenuWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 348 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_MENU_Y]); 349 RegSetValueEx(hKey, TEXT("MenuHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 350 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SCROLL_X]); 351 RegSetValueEx(hKey, TEXT("ScrollWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 352 wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SCROLL_Y]); 353 RegSetValueEx(hKey, TEXT("ScrollHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 354 wsprintf(clText, TEXT("%d"), g->Theme.Size[SIZE_ICON_X]); 355 RegSetValueEx(hKey, TEXT("Shell Icon Sizet"), 0, REG_SZ, (BYTE *)clText, sizeof(clText)); 356 357 RegCloseKey(hKey); 358 } 359 360 /* Effects, save only when needed: */ 361 /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings 362 * Just keep them in sync for now. 363 */ 364 g->Theme.Effects.bTooltipAnimation = g->Theme.Effects.bMenuAnimation; 365 g->Theme.Effects.bTooltipFade = g->Theme.Effects.bMenuFade; 366 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, g->Theme.Effects.bDragFullWindows, NULL, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE); 367 //UPDATE_USERPREF(KEYBOARDCUES, &g->Theme.Effects.bKeyboardCues); 368 //UPDATE_USERPREF(ACTIVEWINDOWTRACKING, &g->Theme.Effects.bActiveWindowTracking); 369 //UPDATE_USERPREF(MENUANIMATION, &g->Theme.Effects.bMenuAnimation); 370 //UPDATE_USERPREF(COMBOBOXANIMATION, &g->Theme.Effects.bComboBoxAnimation); 371 //UPDATE_USERPREF(LISTBOXSMOOTHSCROLLING, &g->Theme.Effects.bListBoxSmoothScrolling); 372 //UPDATE_USERPREF(GRADIENTCAPTIONS, &g->Theme.Effects.bGradientCaptions); 373 //UPDATE_USERPREF(ACTIVEWNDTRKZORDER, &g->Theme.Effects.bActiveWndTrkZorder); 374 //UPDATE_USERPREF(HOTTRACKING, &g->Theme.Effects.bHotTracking); 375 UPDATE_USERPREF(MENUFADE, &g->Theme.Effects.bMenuFade); 376 //UPDATE_USERPREF(SELECTIONFADE, &g->Theme.Effects.bSelectionFade); 377 UPDATE_USERPREF(TOOLTIPANIMATION, &g->Theme.Effects.bTooltipAnimation); 378 UPDATE_USERPREF(TOOLTIPFADE, &g->Theme.Effects.bTooltipFade); 379 //UPDATE_USERPREF(CURSORSHADOW, &g->Theme.Effects.bCursorShadow); 380 //UPDATE_USERPREF(UIEFFECTS, &g->Theme.Effects.bUiEffects); 381 /* Save ThemeId */ 382 Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"), 0, KEY_ALL_ACCESS, &hKey); 383 if (Result == ERROR_SUCCESS) 384 { 385 lstrcpy(clText, g->ThemeTemplates[g->Theme.Id].strKeyName); 386 RegSetValueEx(hKey, TEXT("SelectedStyle"), 0, REG_SZ, (BYTE *)clText, (lstrlen(clText)+1) * sizeof (TCHAR)); 387 RegCloseKey(hKey); 388 } 389 } 390 391 392 static INT_PTR 393 AppearancePage_OnInit(HWND hwndDlg, GLOBALS *g) 394 { 395 HKEY hkNewSchemes, hkScheme, hkSizes, hkSize; 396 FILETIME ftLastWriteTime; 397 TCHAR strSelectedStyle[4]; 398 DWORD dwLength, dwType; 399 DWORD dwDisposition = 0; 400 INT iStyle, iSize, iTemplateIndex, iListIndex = 0; 401 INT Result; 402 403 g = (GLOBALS*)malloc(sizeof(GLOBALS)); 404 if (g == NULL) 405 { 406 return FALSE; 407 } 408 409 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)g); 410 411 LoadCurrentTheme(g); 412 413 /* Fill color schemes combo */ 414 Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"), 415 0, KEY_READ, &hkNewSchemes); 416 if (Result != ERROR_SUCCESS) 417 { 418 /* Could not open the key, try to create it */ 419 Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,&hkNewSchemes, &dwDisposition); 420 if (Result == ERROR_SUCCESS) 421 { 422 /* FIXME: We have created it new, so let's put somethig there */ 423 } 424 } 425 if (Result == ERROR_SUCCESS) 426 { 427 /* First find out the currently selected template */ 428 dwLength = 8; 429 RegQueryValueEx(hkNewSchemes, TEXT("SelectedStyle"), NULL, &dwType, (LPBYTE)&strSelectedStyle, &dwLength); 430 iTemplateIndex = 0; 431 iStyle = 0; 432 dwLength = MAX_TEMPLATENAMELENTGH; 433 while((RegEnumKeyEx(hkNewSchemes, iStyle, g->ThemeTemplates[iTemplateIndex].strKeyName, &dwLength, 434 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iTemplateIndex < MAX_TEMPLATES)) 435 { 436 /* is it really a template or one of the other entries */ 437 if (dwLength < 5) 438 { 439 if (RegOpenKeyEx(hkNewSchemes, g->ThemeTemplates[iTemplateIndex].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS) 440 { 441 if(RegOpenKeyEx(hkScheme, TEXT("Sizes"), 0, KEY_READ, &hkSizes) == ERROR_SUCCESS) 442 { 443 iSize = 0; 444 dwLength = 3; 445 while((RegEnumKeyEx(hkSizes, iSize, g->ThemeTemplates[iTemplateIndex].strSizeName, &dwLength, 446 NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iSize <= 4)) 447 { 448 if(RegOpenKeyEx(hkSizes, g->ThemeTemplates[iTemplateIndex].strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS) 449 { 450 dwLength = MAX_TEMPLATENAMELENTGH; 451 RegQueryValueEx(hkSize, TEXT("DisplayName"), NULL, &dwType, (LPBYTE)&g->ThemeTemplates[iTemplateIndex].strDisplayName, &dwLength); 452 dwLength = MAX_TEMPLATENAMELENTGH; 453 RegQueryValueEx(hkSize, TEXT("LegacyName"), NULL, &dwType, (LPBYTE)&g->ThemeTemplates[iTemplateIndex].strLegacyName, &dwLength); 454 RegCloseKey(hkSize); 455 } 456 iListIndex = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_ADDSTRING, 0, (LPARAM)g->ThemeTemplates[iTemplateIndex].strLegacyName); 457 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_SETITEMDATA, iListIndex, iTemplateIndex); 458 if (lstrcmp(g->ThemeTemplates[iTemplateIndex].strKeyName, strSelectedStyle) == 0) 459 { 460 SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_SETCURSEL, (WPARAM)iListIndex, 0); 461 } 462 iSize++; 463 iTemplateIndex++; 464 dwLength = 3; 465 } 466 RegCloseKey(hkSizes); 467 } 468 RegCloseKey(hkScheme); 469 } 470 } 471 iStyle++; 472 dwLength = MAX_TEMPLATENAMELENTGH; 473 } 474 RegCloseKey(hkNewSchemes); 475 } 476 SendMessage(GetDlgItem(hwndDlg, IDC_APPEARANCE_COLORSCHEME), LB_SETCURSEL, 0, 0); 477 478 return FALSE; 479 } 480 481 482 static INT_PTR 483 AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g) 484 { 485 free(g); 486 return TRUE; 487 } 488 489 490 INT_PTR CALLBACK 491 AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 492 { 493 INT i; 494 GLOBALS *g; 495 LPNMHDR lpnm; 496 497 g = (GLOBALS*)GetWindowLongPtr(hwndDlg, DWLP_USER); 498 499 switch (uMsg) 500 { 501 case WM_INITDIALOG: 502 return AppearancePage_OnInit(hwndDlg, g); 503 504 case WM_DESTROY: 505 return AppearancePage_OnDestroy(hwndDlg, g); 506 507 case WM_COMMAND: 508 switch (LOWORD(wParam)) 509 { 510 case IDC_APPEARANCE_EFFECTS: 511 DialogBoxParam(hApplet, (LPCTSTR)IDD_EFFAPPEARANCE, 512 hwndDlg, EffAppearanceDlgProc, (LPARAM)g); 513 514 /* Was anything changed in the effects appearance dialog? */ 515 if (memcmp(&g->Theme, &g->ThemeAdv, sizeof(THEME)) != 0) 516 { 517 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 518 g->Theme = g->ThemeAdv; 519 g->Theme.bHasChanged = TRUE; 520 } 521 break; 522 523 case IDC_APPEARANCE_ADVANCED: 524 DialogBoxParam(hApplet, (LPCTSTR)IDD_ADVAPPEARANCE, 525 hwndDlg, AdvAppearanceDlgProc, (LPARAM)g); 526 527 /* Was anything changed in the advanced appearance dialog? */ 528 if (memcmp(&g->Theme, &g->ThemeAdv, sizeof(THEME)) != 0) 529 { 530 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 531 g->Theme = g->ThemeAdv; 532 g->Theme.bHasChanged = TRUE; 533 } 534 break; 535 536 case IDC_APPEARANCE_COLORSCHEME: 537 if(HIWORD(wParam) == CBN_SELCHANGE) 538 { 539 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 540 g->Theme.bHasChanged = TRUE; 541 i = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETCURSEL, 0, 0); 542 g->Theme.Id = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETITEMDATA, (WPARAM)i, 0); 543 LoadThemeFromReg(g); 544 //SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, WM_PAINT, 0, 0); 545 } 546 break; 547 548 default: 549 return FALSE; 550 } 551 return TRUE; 552 553 case WM_NOTIFY: 554 lpnm = (LPNMHDR)lParam; 555 switch (lpnm->code) 556 { 557 case PSN_APPLY: 558 if (g->Theme.bHasChanged) 559 { 560 ApplyTheme(g); 561 } 562 return TRUE; 563 564 default: 565 return FALSE; 566 } 567 return TRUE; 568 569 default: 570 return FALSE; 571 } 572 573 return TRUE; 574 } 575