Sync with trunk (48237)
[reactos.git] / dll / cpl / desk / appearance.c
index c3c21d4..b55e379 100644 (file)
  */
 
 #include "desk.h"
+#include "theme.h"
+#include "preview.h"
 #include "appearance.h"
 
 /******************************************************************************/
 
-/* This const assigns the color and metric numbers to the elements from the elements list */
-
-/* Size 1 (width)      Size 2 (height) Color 1                                 Color 2                                                 Font                    Fontcolor */
-const ASSIGNMENT g_Assignment[NUM_ELEMENTS] =
-{ {-1,                         -1,                             COLOR_DESKTOP,                  -1,                                                             -1,                             -1},                            /* -Desktop */
-  {SIZE_CAPTION_Y,     -1,                             COLOR_INACTIVECAPTION,  COLOR_GRADIENTINACTIVECAPTION,  FONT_CAPTION,   -1},                            /* inactive window caption */
-  {SIZE_BORDER_X,      SIZE_BORDER_Y,  COLOR_INACTIVEBORDER,   -1,                                                             -1,                             -1},                            /* inactive window border */
-  {SIZE_CAPTION_Y,     -1,                             COLOR_ACTIVECAPTION,    COLOR_GRADIENTACTIVECAPTION,    FONT_CAPTION,   COLOR_CAPTIONTEXT},     /* -active window caption */
-  {SIZE_BORDER_X,      SIZE_BORDER_Y,  COLOR_ACTIVEBORDER,             -1,                                                             -1,                             -1},                            /* active window border */
-  {SIZE_MENU_X,                SIZE_MENU_Y,    COLOR_MENU,                             -1,                                                     FONT_MENU,              COLOR_MENUTEXT},        /* menu */
-  {SIZE_MENU_X,                SIZE_MENU_Y,    COLOR_HIGHLIGHT,                -1,                                                             FONT_HILIGHT,   COLOR_HIGHLIGHTTEXT},/* marked element */
-  {-1,                         -1,                             COLOR_WINDOW,                   -1 /*COLOR_WINDOWFRAME*/,                               -1,                             COLOR_WINDOWTEXT},      /* window */
-  {SIZE_SCROLL_X,      SIZE_SCROLL_Y,  COLOR_SCROLLBAR,                -1,                                                             -1,                             -1},                            /* scroll bar */
-  {-1,                         -1,                             COLOR_3DFACE,                   -1,                                                             -1,                             COLOR_BTNTEXT},         /* 3d objects */
-  {SIZE_SMCAPTION_Y,-1,                                -1,                                             -1,                                                             FONT_SMCAPTION, -1},                            /* palette window caption */
-  {-1,                         -1,                             -1,                                             -1,                                                             -1,                             -1},                            /* symbol caption FIXME: Access? */
-  {SIZE_CAPTION_Y,     -1,                             -1,                                             -1,                                                             -1,                             -1},                            /* caption bar */
-  {-1,                         -1,                             -1,                                             -1,                                                             -1,                             COLOR_GRAYTEXT},        /* inactive menu item FIXME: Access? */
-  {-1,                         -1,                             -1,                                             -1,                                                             FONT_DIALOG,    COLOR_WINDOWTEXT},      /* dialog */
-  {-1,                         -1,                             -1,                                             -1,                                                             -1,                             -1},                            /* scrollbar controls FIXME: Access? */
-  {-1,                         -1,                             COLOR_APPWORKSPACE,             -1,                                                             -1,                             -1},                            /* application background */
-  {-1,                         -1,                             -1,                                             -1,                                                             -1,                             -1},                            /* small caption bar FIXME: Access? */
-  {SIZE_ICON_SPC_X,    -1,                             -1,                                             -1,                                                             -1,                             -1},                            /* symbol distance horiz. */
-  {SIZE_ICON_SPC_Y,    -1,                             -1,                                             -1,                                                             -1,                             -1},                            /* symbol distance vert. */
-  {-1,                         -1,                             COLOR_INFOBK,                   -1,                                                             FONT_INFO,              COLOR_INFOTEXT},        /* quickinfo */
-  {SIZE_ICON_X,                SIZE_ICON_Y,    -1,                                             -1,                                                             FONT_ICON,              -1}};                           /* symbol */
-
-/* This is the list of names for the colors stored in the registry */
-const TCHAR g_RegColorNames[NUM_COLORS][MAX_COLORNAMELENGTH] =
-       {TEXT("Scrollbar"),                             /* 00 = COLOR_SCROLLBAR */
-       TEXT("Background"),                             /* 01 = COLOR_DESKTOP */
-       TEXT("ActiveTitle"),                    /* 02 = COLOR_ACTIVECAPTION  */
-       TEXT("InactiveTitle"),                  /* 03 = COLOR_INACTIVECAPTION */
-       TEXT("Menu"),                                   /* 04 = COLOR_MENU */
-       TEXT("Window"),                                 /* 05 = COLOR_WINDOW */
-       TEXT("WindowFrame"),                    /* 06 = COLOR_WINDOWFRAME */
-       TEXT("MenuText"),                               /* 07 = COLOR_MENUTEXT */
-       TEXT("WindowText"),                     /* 08 = COLOR_WINDOWTEXT */
-       TEXT("TitleText"),                              /* 09 = COLOR_CAPTIONTEXT */
-       TEXT("ActiveBorder"),                   /* 10 = COLOR_ACTIVEBORDER */
-       TEXT("InactiveBorder"),                 /* 11 = COLOR_INACTIVEBORDER */
-       TEXT("AppWorkSpace"),                   /* 12 = COLOR_APPWORKSPACE */
-       TEXT("Hilight"),                                /* 13 = COLOR_HIGHLIGHT */
-       TEXT("HilightText"),                    /* 14 = COLOR_HIGHLIGHTTEXT */
-       TEXT("ButtonFace"),                     /* 15 = COLOR_BTNFACE */
-       TEXT("ButtonShadow"),                   /* 16 = COLOR_BTNSHADOW */
-       TEXT("GrayText"),                               /* 17 = COLOR_GRAYTEXT */
-       TEXT("ButtonText"),                     /* 18 = COLOR_BTNTEXT */
-       TEXT("InactiveTitleText"),              /* 19 = COLOR_INACTIVECAPTIONTEXT */
-       TEXT("ButtonHilight"),                  /* 20 = COLOR_BTNHIGHLIGHT */
-       TEXT("ButtonDkShadow"),                 /* 21 = COLOR_3DDKSHADOW */
-       TEXT("ButtonLight"),                    /* 22 = COLOR_3DLIGHT */
-       TEXT("InfoText"),                               /* 23 = COLOR_INFOTEXT */
-       TEXT("InfoWindow"),                     /* 24 = COLOR_INFOBK */
-       TEXT("ButtonAlternateFace"),    /* 25 = COLOR_ALTERNATEBTNFACE */
-       TEXT("HotTrackingColor"),               /* 26 = COLOR_HOTLIGHT */
-       TEXT("GradientActiveTitle"),    /* 27 = COLOR_GRADIENTACTIVECAPTION */
-       TEXT("GradientInactiveTitle"),  /* 28 = COLOR_GRADIENTINACTIVECAPTION */
-       TEXT("MenuHilight"),                    /* 29 = COLOR_MENUHILIGHT */
-       TEXT("MenuBar"),                                /* 30 = COLOR_MENUBAR */
-};
-
-/* This is the list of used metrics and their numbers */
-const int g_SizeMetric[NUM_SIZES] =
-{
-       SM_CXBORDER,
-       SM_CYBORDER,
-       SM_CYCAPTION,
-       SM_CXICON,
-       SM_CYICON,
-       SM_CXICONSPACING,
-       SM_CYICONSPACING,
-       SM_CXMENUSIZE,
-       SM_CYMENU,
-       SM_CXVSCROLL,
-       SM_CYHSCROLL,
-       SM_CYSMCAPTION
-};
-
-/******************************************************************************/
-
-static VOID
-LoadCurrentTheme(GLOBALS* g)
-{
-       INT i;
-       NONCLIENTMETRICS NonClientMetrics;
-
-       g->Theme.bHasChanged = FALSE;
-       /* FIXME: it may be custom! */
-       g->Theme.bIsCustom = FALSE;
-
-       /* Load colors */
-       for (i = 0; i <= 30; i++)
-       {
-               g->ColorList[i] = i;
-               g->Theme.crColor[i] = (COLORREF)GetSysColor(i);
-       }
-
-       /* Load sizes */
-       for (i = 0; i <= 11; i++)
-       {
-               g->Theme.Size[i] = GetSystemMetrics(g_SizeMetric[i]);
-       }
-
-       /* Load fonts */
-       NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);
-       SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
-       g->Theme.lfFont[FONT_CAPTION] = NonClientMetrics.lfCaptionFont;
-       g->Theme.lfFont[FONT_SMCAPTION] = NonClientMetrics.lfSmCaptionFont;
-       g->Theme.lfFont[FONT_MENU] = NonClientMetrics.lfMenuFont;
-       g->Theme.lfFont[FONT_INFO] = NonClientMetrics.lfStatusFont;
-       g->Theme.lfFont[FONT_DIALOG] = NonClientMetrics.lfMessageFont;
-       SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &g->Theme.lfFont[FONT_ICON], 0);
-
-    /* Effects */
-   /* "Use the following transition effect for menus and tooltips" */
-    SystemParametersInfo(SPI_GETMENUANIMATION, sizeof(BOOL), &g->Theme.Effects.bMenuAnimation, 0);
-    SystemParametersInfo(SPI_GETMENUFADE, sizeof(BOOL), &g->Theme.Effects.bMenuFade, 0);
-    /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings
-     * Just keep them in sync for now:
-     */
-    g->Theme.Effects.bTooltipAnimation  = g->Theme.Effects.bMenuAnimation;
-    g->Theme.Effects.bTooltipFade       = g->Theme.Effects.bMenuFade;
-
-    /* show content of windows during dragging */
-    //SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, g->Theme.Effects.bDragFullWindows, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
-    SystemParametersInfoW(SPI_GETDRAGFULLWINDOWS, 0, &g->Theme.Effects.bDragFullWindows, 0);
-
-    /* "Hide underlined letters for keyboard navigation until I press the Alt key" */
-    SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &g->Theme.Effects.bKeyboardCues, 0);
-}
-
-
-static BOOL
-LoadThemeFromReg(GLOBALS* g)
-{
-       INT i;
-       TCHAR strSizeName[20] = {TEXT("Sizes\\0")};
-       TCHAR strValueName[10];
-       HKEY hkNewSchemes, hkScheme, hkSize;
-       DWORD dwType, dwLength;
-       BOOL Ret = FALSE;
-       INT iPreset = g->Theme.Id;
-
-       if(RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"),
-               0, KEY_READ, &hkNewSchemes) == ERROR_SUCCESS)
-       {
-               if(RegOpenKeyEx(hkNewSchemes, g->ThemeTemplates[iPreset].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS)
-               {
-                       lstrcpyn(&strSizeName[6],g->ThemeTemplates[iPreset].strSizeName, 3);
-                       if(RegOpenKeyEx(hkScheme, strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS)
-                       {
-                               Ret = TRUE;
-
-                               dwLength = sizeof(DWORD);
-                               if (RegQueryValueEx(hkSize, TEXT("FlatMenus"), NULL, &dwType, (LPBYTE)&g->Theme.bFlatMenus, &dwLength) != ERROR_SUCCESS ||
-                                   dwType != REG_DWORD || dwLength != sizeof(DWORD))
-                               {
-                                       /* Failed to read registry value */
-                                       g->Theme.bFlatMenus = FALSE;
-                                       Ret = FALSE;
-                               }
-
-                               for (i = 0; i <= 30; i++)
-                               {
-                                       wsprintf(strValueName, TEXT("Color #%d"), i);
-                                       dwLength = sizeof(COLORREF);
-                                       if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&g->Theme.crColor[i], &dwLength) != ERROR_SUCCESS ||
-                                           dwType != REG_DWORD || dwLength != sizeof(COLORREF))
-                                       {
-                                               /* Failed to read registry value, initialize with current setting for now */
-                                               g->Theme.crColor[i] = GetSysColor(i);
-                                               Ret = FALSE;
-                                       }
-                               }
-                               for (i = 0; i <= 5; i++)
-                               {
-                                       wsprintf(strValueName, TEXT("Font #%d"), i);
-                                       dwLength = sizeof(LOGFONT);
-                                       g->Theme.lfFont[i].lfFaceName[0] = 'x';
-                                       if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&g->Theme.lfFont[i], &dwLength) != ERROR_SUCCESS ||
-                                           dwType != REG_BINARY || dwLength != sizeof(LOGFONT))
-                                       {
-                                               /* Failed to read registry value */
-                                               Ret = FALSE;
-                                       }
-                               }
-                               for (i = 0; i <= 8; i++)
-                               {
-                                       wsprintf(strValueName, TEXT("Size #%d"), i);
-                                       dwLength = sizeof(UINT64);
-                                       if (RegQueryValueEx(hkSize, strValueName, NULL, &dwType, (LPBYTE)&g->Theme.Size[i], &dwLength) != ERROR_SUCCESS ||
-                                           dwType != REG_QWORD || dwLength != sizeof(UINT64))
-                                       {
-                                               /* Failed to read registry value, initialize with current setting for now */
-                                               g->Theme.Size[i] = GetSystemMetrics(g_SizeMetric[i]);
-                                               Ret = FALSE;
-                                       }
-                               }
-                               RegCloseKey(hkScheme);
-                       }
-                       RegCloseKey(hkScheme);
-               }
-               RegCloseKey(hkNewSchemes);
-       }
-
-       return Ret;
-}
-
-static VOID
-_UpdateUserPref(UINT SpiGet,UINT SpiSet,BOOL *pbFlag)
-{
-    SystemParametersInfo(SpiSet, 0, (PVOID)pbFlag, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
-}
-#define UPDATE_USERPREF(NAME,pbFlag) _UpdateUserPref(SPI_GET ## NAME, SPI_SET ## NAME, pbFlag)
-
-static VOID
-ApplyTheme(GLOBALS* g)
-{
-       INT i, Result;
-       HKEY hKey;
-       DWORD dwDisposition = 0;
-       TCHAR clText[16] = {0};
-       NONCLIENTMETRICS NonClientMetrics;
-       HFONT hMyFont;
-       LOGFONT lfButtonFont;
-
-       if (!g->Theme.bHasChanged)
-               return;
-
-       /* Update some globals */
-       g->crCOLOR_BTNFACE = g->Theme.crColor[COLOR_BTNFACE];
-       g->crCOLOR_BTNTEXT = g->Theme.crColor[COLOR_BTNTEXT];
-       g->crCOLOR_BTNSHADOW = g->Theme.crColor[COLOR_BTNSHADOW];
-       g->crCOLOR_BTNHIGHLIGHT = g->Theme.crColor[COLOR_BTNHIGHLIGHT];
-       lfButtonFont = g->Theme.lfFont[FONT_DIALOG];
-
-       /* Create new font for bold button */
-       lfButtonFont.lfWeight = FW_BOLD;
-       lfButtonFont.lfItalic = FALSE;
-       hMyFont = CreateFontIndirect(&lfButtonFont);
-       if (hMyFont)
-       {
-               if (g->hBoldFont)
-                       DeleteObject(g->hBoldFont);
-               g->hBoldFont = hMyFont;
-       }
-
-       /* Create new font for italic button */
-       lfButtonFont.lfWeight = FW_REGULAR;
-       lfButtonFont.lfItalic = TRUE;
-       hMyFont = CreateFontIndirect(&lfButtonFont);
-       if (hMyFont)
-       {
-               if (g->hItalicFont)
-                       DeleteObject(g->hItalicFont);
-               g->hItalicFont = hMyFont;
-       }
-
-       /* Apply Colors from global variable */
-       SetSysColors(30, &g->ColorList[0], &g->Theme.crColor[0]);
-
-       /* Save colors to registry */
-       Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, KEY_ALL_ACCESS, &hKey);
-       if (Result != ERROR_SUCCESS)
-       {
-               /* Could not open the key, try to create it */
-               Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Colors"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,&hKey, &dwDisposition);
-       }
-
-       if (Result == ERROR_SUCCESS)
-       {
-               for (i = 0; i <= 30; i++)
-               {
-                       DWORD red   = GetRValue(g->Theme.crColor[i]);
-                       DWORD green = GetGValue(g->Theme.crColor[i]);
-                       DWORD blue  = GetBValue(g->Theme.crColor[i]);
-                       wsprintf(clText, TEXT("%d %d %d"), red, green, blue);
-                       RegSetValueEx(hKey, g_RegColorNames[i], 0, REG_SZ, (BYTE *)clText, lstrlen( clText )*sizeof(TCHAR) + sizeof(TCHAR));
-               }
-
-               RegCloseKey(hKey);
-       }
-
-       /* Apply the fonts */
-       NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);
-       SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
-       NonClientMetrics.lfCaptionFont = g->Theme.lfFont[FONT_CAPTION];
-       NonClientMetrics.lfSmCaptionFont = g->Theme.lfFont[FONT_SMCAPTION];
-       NonClientMetrics.lfMenuFont = g->Theme.lfFont[FONT_MENU];
-       NonClientMetrics.lfStatusFont = g->Theme.lfFont[FONT_INFO];
-       NonClientMetrics.lfMessageFont = g->Theme.lfFont[FONT_DIALOG];
-       SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);
-       SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(LOGFONT), &g->Theme.lfFont[FONT_ICON], 0);
-
-       /* FIXME: Apply size metrics */
-
-       /* Save fonts and size metrics to registry */
-       Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, KEY_ALL_ACCESS, &hKey);
-       if (Result != ERROR_SUCCESS)
-       {
-               /* Could not open the key, try to create it */
-               Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,&hKey, &dwDisposition);
-       }
-
-       if (Result == ERROR_SUCCESS)
-       {
-               RegSetValueEx(hKey, TEXT("CaptionFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_CAPTION], sizeof(LOGFONT));
-               RegSetValueEx(hKey, TEXT("SmCaptionFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_SMCAPTION], sizeof(LOGFONT));
-               RegSetValueEx(hKey, TEXT("IconFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_ICON], sizeof(LOGFONT));
-               RegSetValueEx(hKey, TEXT("MenuFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_MENU], sizeof(LOGFONT));
-               RegSetValueEx(hKey, TEXT("StatusFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_INFO], sizeof(LOGFONT));
-               RegSetValueEx(hKey, TEXT("MessageFont"), 0, REG_BINARY, (BYTE *)&g->Theme.lfFont[FONT_DIALOG], sizeof(LOGFONT));
-
-               /* Save size metrics to registry */
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_BORDER_X]);
-               RegSetValueEx(hKey, TEXT("BorderWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_CAPTION_Y]);
-               RegSetValueEx(hKey, TEXT("CaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_CAPTION_Y]);
-               RegSetValueEx(hKey, TEXT("CaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SMCAPTION_Y]);
-               RegSetValueEx(hKey, TEXT("SmCaptionWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SMCAPTION_Y]);
-               RegSetValueEx(hKey, TEXT("SmCaptionHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_ICON_SPC_X]);
-               RegSetValueEx(hKey, TEXT("IconSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_ICON_SPC_Y]);
-               RegSetValueEx(hKey, TEXT("IconVerticalSpacing"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_MENU_X]);
-               RegSetValueEx(hKey, TEXT("MenuWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_MENU_Y]);
-               RegSetValueEx(hKey, TEXT("MenuHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SCROLL_X]);
-               RegSetValueEx(hKey, TEXT("ScrollWidth"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), -15 * g->Theme.Size[SIZE_SCROLL_Y]);
-               RegSetValueEx(hKey, TEXT("ScrollHeight"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-               wsprintf(clText, TEXT("%d"), g->Theme.Size[SIZE_ICON_X]);
-               RegSetValueEx(hKey, TEXT("Shell Icon Sizet"), 0, REG_SZ, (BYTE *)clText, sizeof(clText));
-
-               RegCloseKey(hKey);
-       }
-
-    /* Effects, save only when needed: */
-    /* FIXME: XP seems to use grayed checkboxes to reflect differences between menu and tooltips settings
-     * Just keep them in sync for now.
-     */
-    g->Theme.Effects.bTooltipAnimation  = g->Theme.Effects.bMenuAnimation;
-    g->Theme.Effects.bTooltipFade       = g->Theme.Effects.bMenuFade;
-    SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, g->Theme.Effects.bDragFullWindows, NULL, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
-    //UPDATE_USERPREF(KEYBOARDCUES, &g->Theme.Effects.bKeyboardCues);
-    //UPDATE_USERPREF(ACTIVEWINDOWTRACKING, &g->Theme.Effects.bActiveWindowTracking);
-    //UPDATE_USERPREF(MENUANIMATION, &g->Theme.Effects.bMenuAnimation);
-    //UPDATE_USERPREF(COMBOBOXANIMATION, &g->Theme.Effects.bComboBoxAnimation);
-    //UPDATE_USERPREF(LISTBOXSMOOTHSCROLLING, &g->Theme.Effects.bListBoxSmoothScrolling);
-    //UPDATE_USERPREF(GRADIENTCAPTIONS, &g->Theme.Effects.bGradientCaptions);
-    //UPDATE_USERPREF(ACTIVEWNDTRKZORDER, &g->Theme.Effects.bActiveWndTrkZorder);
-    //UPDATE_USERPREF(HOTTRACKING, &g->Theme.Effects.bHotTracking);
-    UPDATE_USERPREF(MENUFADE, &g->Theme.Effects.bMenuFade);
-    //UPDATE_USERPREF(SELECTIONFADE, &g->Theme.Effects.bSelectionFade);
-    UPDATE_USERPREF(TOOLTIPANIMATION, &g->Theme.Effects.bTooltipAnimation);
-    UPDATE_USERPREF(TOOLTIPFADE, &g->Theme.Effects.bTooltipFade);
-    //UPDATE_USERPREF(CURSORSHADOW, &g->Theme.Effects.bCursorShadow);
-    //UPDATE_USERPREF(UIEFFECTS, &g->Theme.Effects.bUiEffects);
-       /* Save ThemeId */
-       Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"), 0, KEY_ALL_ACCESS, &hKey);
-       if (Result == ERROR_SUCCESS)
-       {
-               lstrcpy(clText, g->ThemeTemplates[g->Theme.Id].strKeyName);
-               RegSetValueEx(hKey, TEXT("SelectedStyle"), 0, REG_SZ, (BYTE *)clText, (lstrlen(clText)+1) * sizeof (TCHAR));
-               RegCloseKey(hKey);
-       }
-}
-
-
 static INT_PTR
-AppearancePage_OnInit(HWND hwndDlg, GLOBALS *g)
+AppearancePage_OnInit(HWND hwndDlg)
 {
-       HKEY hkNewSchemes, hkScheme, hkSizes, hkSize;
-       FILETIME ftLastWriteTime;
        TCHAR strSelectedStyle[4];
-       DWORD dwLength, dwType;
-       DWORD dwDisposition = 0;
-       INT iStyle, iSize, iTemplateIndex, iListIndex = 0;
-       INT Result;
+       INT i, TemplateCount, iListIndex;
+       HWND hwndCombo;
+       GLOBALS *g;
 
-       g = (GLOBALS*)malloc(sizeof(GLOBALS));
+       g = (GLOBALS*)LocalAlloc(LPTR, sizeof(GLOBALS));
        if (g == NULL)
-       {
                return FALSE;
-       }
 
        SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)g);
 
-       LoadCurrentTheme(g);
+       LoadCurrentTheme(&g->Theme);
+       g->ThemeAdv = g->Theme;
+       g->bHasChanged = FALSE;
+       g->hBoldFont = g->hItalicFont = NULL;
+       g->hbmpColor[0] = g->hbmpColor[1] = g->hbmpColor[2] = NULL;
+       g->bInitializing = FALSE;
 
-       /* Fill color schemes combo */
-       Result = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"),
-               0, KEY_READ, &hkNewSchemes);
-       if (Result != ERROR_SUCCESS)
-       {
-               /* Could not open the key, try to create it */
-               Result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Appearance\\New Schemes"), 0, NULL, 0, KEY_ALL_ACCESS, NULL,&hkNewSchemes, &dwDisposition);
-               if (Result == ERROR_SUCCESS)
-               {
-                       /* FIXME: We have created it new, so let's put somethig there */
-               }
-       }
-       if (Result == ERROR_SUCCESS)
+       TemplateCount = LoadThemePresetEntries(strSelectedStyle);
+
+       hwndCombo = GetDlgItem(hwndDlg, IDC_APPEARANCE_COLORSCHEME);
+       g->ThemeId = -1;
+       g->bInitializing = TRUE;
+       for(i = 0; i < TemplateCount; i++)
        {
-               /* First find out the currently selected template */
-               dwLength = 8;
-               RegQueryValueEx(hkNewSchemes, TEXT("SelectedStyle"), NULL, &dwType, (LPBYTE)&strSelectedStyle, &dwLength);
-               iTemplateIndex = 0;
-               iStyle = 0;
-               dwLength = MAX_TEMPLATENAMELENTGH;
-               while((RegEnumKeyEx(hkNewSchemes, iStyle, g->ThemeTemplates[iTemplateIndex].strKeyName, &dwLength,
-                       NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iTemplateIndex < MAX_TEMPLATES))
+               iListIndex = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)g_ThemeTemplates[i].strLegacyName);
+               SendMessage(hwndCombo, CB_SETITEMDATA, iListIndex, i);
+               if (lstrcmp(g_ThemeTemplates[i].strKeyName, strSelectedStyle) == 0)
                {
-                       /* is it really a template or one of the other entries */
-                       if (dwLength < 5)
-                       {
-                               if (RegOpenKeyEx(hkNewSchemes, g->ThemeTemplates[iTemplateIndex].strKeyName, 0, KEY_READ, &hkScheme) == ERROR_SUCCESS)
-                               {
-                                       if(RegOpenKeyEx(hkScheme, TEXT("Sizes"), 0, KEY_READ, &hkSizes) == ERROR_SUCCESS)
-                                       {
-                                               iSize = 0;
-                                               dwLength = 3;
-                                               while((RegEnumKeyEx(hkSizes, iSize, g->ThemeTemplates[iTemplateIndex].strSizeName, &dwLength,
-                                                       NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) && (iSize <= 4))
-                                               {
-                                                       if(RegOpenKeyEx(hkSizes, g->ThemeTemplates[iTemplateIndex].strSizeName, 0, KEY_READ, &hkSize) == ERROR_SUCCESS)
-                                                       {
-                                                               dwLength = MAX_TEMPLATENAMELENTGH;
-                                                               RegQueryValueEx(hkSize, TEXT("DisplayName"), NULL, &dwType, (LPBYTE)&g->ThemeTemplates[iTemplateIndex].strDisplayName, &dwLength);
-                                                               dwLength = MAX_TEMPLATENAMELENTGH;
-                                                               RegQueryValueEx(hkSize, TEXT("LegacyName"), NULL, &dwType, (LPBYTE)&g->ThemeTemplates[iTemplateIndex].strLegacyName, &dwLength);
-                                                               RegCloseKey(hkSize);
-                                                       }
-                                                       iListIndex = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_ADDSTRING, 0, (LPARAM)g->ThemeTemplates[iTemplateIndex].strLegacyName);
-                                                       SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_SETITEMDATA, iListIndex, iTemplateIndex);
-                                                       if (lstrcmp(g->ThemeTemplates[iTemplateIndex].strKeyName, strSelectedStyle) == 0)
-                                                       {
-                                                               SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_SETCURSEL, (WPARAM)iListIndex, 0);
-                                                       }
-                                                       iSize++;
-                                                       iTemplateIndex++;
-                                                       dwLength = 3;
-                                               }
-                                               RegCloseKey(hkSizes);
-                                       }
-                                       RegCloseKey(hkScheme);
-                               }
-                       }
-                       iStyle++;
-                       dwLength = MAX_TEMPLATENAMELENTGH;
+                       g->ThemeId = i;
+                       SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM)iListIndex, 0);
                }
-               RegCloseKey(hkNewSchemes);
        }
-       SendMessage(GetDlgItem(hwndDlg, IDC_APPEARANCE_COLORSCHEME), LB_SETCURSEL, 0, 0);
+       g->bInitializing = FALSE;
 
        return FALSE;
 }
 
-
-static INT_PTR
+static VOID
 AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g)
 {
-       free(g);
-       return TRUE;
+       LocalFree(g);
 }
 
-static void
-UpdateSelectedThemeId(HWND hwndDlg, GLOBALS *g)
+static INT
+GetSelectedThemeId(HWND hwndDlg)
 {
-       int sel;
-       sel = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETCURSEL, 0, 0);
-       g->Theme.Id = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETITEMDATA, (WPARAM)sel, 0);
+       HWND hwndCombo;
+       INT sel;
+
+       hwndCombo = GetDlgItem(hwndDlg, IDC_APPEARANCE_COLORSCHEME);
+       sel = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
+       if (sel == CB_ERR)
+               return -1;
+       return (INT)SendMessage(hwndCombo, CB_GETITEMDATA, (WPARAM)sel, 0);
 }
 
 INT_PTR CALLBACK
@@ -504,76 +86,83 @@ AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
        switch (uMsg)
        {
                case WM_INITDIALOG:
-                       return AppearancePage_OnInit(hwndDlg, g);
+                       return AppearancePage_OnInit(hwndDlg);
 
                case WM_DESTROY:
-                       return AppearancePage_OnDestroy(hwndDlg, g);
+                       AppearancePage_OnDestroy(hwndDlg, g);
+                       break;
 
                case WM_COMMAND:
                        switch (LOWORD(wParam))
                        {
                                case IDC_APPEARANCE_EFFECTS:
-                                       DialogBoxParam(hApplet, (LPCTSTR)IDD_EFFAPPEARANCE,
-                                               hwndDlg, EffAppearanceDlgProc, (LPARAM)g);
-
-                                       /* Was anything changed in the effects appearance dialog? */
-                                       if (memcmp(&g->Theme, &g->ThemeAdv, sizeof(THEME)) != 0)
+                                       if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_EFFAPPEARANCE),
+                                                                          hwndDlg, EffAppearanceDlgProc, (LPARAM)g) == IDOK)
                                        {
                                                PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                                                g->Theme = g->ThemeAdv;
-                                               g->Theme.bHasChanged = TRUE;
+                                               g->bHasChanged = TRUE;
+                                               g->ThemeId = -1;        /* Customized */
+                                               SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_SETCURSEL, (WPARAM)-1, 0);
+                                               SetDlgItemText(hwndDlg, IDC_APPEARANCE_COLORSCHEME, TEXT(""));
+                                               SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_UPDATETHEME, 0, (LPARAM)&g->Theme);
                                        }
                                        break;
 
                                case IDC_APPEARANCE_ADVANCED:
-                                       DialogBoxParam(hApplet, (LPCTSTR)IDD_ADVAPPEARANCE,
-                                               hwndDlg, AdvAppearanceDlgProc, (LPARAM)g);
-
-                                       /* Was anything changed in the advanced appearance dialog? */
-                                       if (memcmp(&g->Theme, &g->ThemeAdv, sizeof(THEME)) != 0)
+                                       if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_ADVAPPEARANCE),
+                                                                          hwndDlg, AdvAppearanceDlgProc, (LPARAM)g) == IDOK)
                                        {
                                                PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                                                g->Theme = g->ThemeAdv;
-                                               g->Theme.bHasChanged = TRUE;
+                                               g->bHasChanged = TRUE;
+                                               g->ThemeId = -1;        /* Customized */
+                                               SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_SETCURSEL, (WPARAM)-1, 0);
+                                               SetDlgItemText(hwndDlg, IDC_APPEARANCE_COLORSCHEME, TEXT(""));
+                                               SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_UPDATETHEME, 0, (LPARAM)&g->Theme);
                                        }
                                        break;
 
                                case IDC_APPEARANCE_COLORSCHEME:
-                                       if(HIWORD(wParam) == CBN_SELCHANGE)
+                                       if (HIWORD(wParam) == CBN_SELCHANGE && !g->bInitializing)
                                        {
+                                               THEME Theme;
+                                               INT ThemeId = GetSelectedThemeId(hwndDlg);
                                                PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
-                                               g->Theme.bHasChanged = TRUE;
-                                               UpdateSelectedThemeId(hwndDlg, g);
-                                               LoadThemeFromReg(g);
-                                               //SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, WM_PAINT, 0, 0);
+                                               g->bHasChanged = TRUE;
+                                               if (ThemeId != -1 && LoadThemeFromReg(&Theme, ThemeId))
+                                               {
+                                                       g->Theme = Theme;
+                                                       g->ThemeId = ThemeId;
+                                                       SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_UPDATETHEME, 0, (LPARAM)&Theme);
+                                               }
                                        }
                                        break;
-
-                               default:
-                                       return FALSE;
                        }
-                       return TRUE;
+                       break;
 
                case WM_NOTIFY:
                        lpnm = (LPNMHDR)lParam;
                        switch (lpnm->code)
                        {
                                case PSN_APPLY:
-                                       if (g->Theme.bHasChanged)
+                                       if (g->bHasChanged)
                                        {
-                                               UpdateSelectedThemeId(hwndDlg, g);
-                                               ApplyTheme(g);
+                                               INT ThemeId = GetSelectedThemeId(hwndDlg);
+                                               ApplyTheme(&g->Theme, ThemeId);
+                                               g->ThemeId = ThemeId;
+                                               SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, PVM_UPDATETHEME, 0, (LPARAM)&g->Theme);
+                                               g->bHasChanged = FALSE;
                                        }
+                                       SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)PSNRET_NOERROR);
                                        return TRUE;
 
-                               default:
-                                       return FALSE;
+                               case PSN_KILLACTIVE:
+                                       SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)FALSE);
+                                       return TRUE;
                        }
-                       return TRUE;
-
-               default:
-                       return FALSE;
+                       break;
        }
 
-       return TRUE;
+       return FALSE;
 }