[SHELL32] Fix item order in Folder Options (#415)
[reactos.git] / dll / win32 / shell32 / dialogs / folder_options.cpp
index 7644568..197b301 100644 (file)
@@ -2,6 +2,7 @@
  *    Open With  Context Menu extension
  *
  * Copyright 2007 Johannes Anderwald <johannes.anderwald@reactos.org>
+ * Copyright 2016-2017 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,8 +23,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL (fprop);
 
-#define MAX_PROPERTY_SHEET_PAGE (32)
-
 /// Folder Options:
 /// CLASSKEY = HKEY_CLASSES_ROOT\CLSID\{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}
 /// DefaultIcon = %SystemRoot%\system32\SHELL32.dll,-210
@@ -37,53 +36,833 @@ typedef struct
     WCHAR FileExtension[30];
     WCHAR FileDescription[100];
     WCHAR ClassKey[MAX_PATH];
+    DWORD EditFlags;
 } FOLDER_FILE_TYPE_ENTRY, *PFOLDER_FILE_TYPE_ENTRY;
 
-typedef struct
+// uniquely-defined icon entry for Advanced Settings
+typedef struct ADVANCED_ICON
 {
-    LPCWSTR szKeyName;
-    UINT ResourceID;
-} FOLDER_VIEW_ENTRY, PFOLDER_VIEW_ENTRY;
-/*
-static FOLDER_VIEW_ENTRY s_Options[] =
-{
-    { L"AlwaysShowMenus", IDS_ALWAYSSHOWMENUS },
-    { L"AutoCheckSelect", -1 },
-    { L"ClassicViewState", -1 },
-    { L"DontPrettyPath",  -1 },
-    { L"Filter", -1 },
-    { L"FolderContentsInfoTip", IDS_FOLDERCONTENTSTIP },
-    { L"FriendlyTree", -1 },
-    { L"Hidden", -1, },
-    { L"HideFileExt", IDS_HIDEFILEEXT },
-    { L"HideIcons", -1},
-    { L"IconsOnly", -1},
-    { L"ListviewAlphaSelect", -1},
-    { L"ListviewShadow", -1},
-    { L"ListviewWatermark", -1},
-    { L"MapNetDrvBtn", -1},
-    { L"PersistBrowsers", -1},
-    { L"SeperateProcess", IDS_SEPERATEPROCESS},
-    { L"ServerAdminUI", -1},
-    { L"SharingWizardOn", IDS_USESHAREWIZARD},
-    { L"ShowCompColor", IDS_COMPCOLOR},
-    { L"ShowInfoTip", IDS_SHOWINFOTIP},
-    { L"ShowPreviewHandlers", -1},
-    { L"ShowSuperHidden", IDS_HIDEOSFILES},
-    { L"ShowTypeOverlay", -1},
-    { L"Start_ShowMyGames", -1},
-    { L"StartMenuInit", -1},
-    { L"SuperHidden", -1},
-    { L"TypeAhead", -1},
-    { L"Webview", -1},
-    { NULL, -1}
-
-};
-*/
+    WCHAR   szPath[MAX_PATH];
+    UINT    nIconIndex;
+} ADVANCED_ICON;
+
+// predefined icon IDs (See CreateTreeImageList function below)
+#define I_CHECKED                   0
+#define I_UNCHECKED                 1
+#define I_CHECKED_DISABLED          2
+#define I_UNCHECKED_DISABLED        3
+#define I_RADIO_CHECKED             4
+#define I_RADIO_UNCHECKED           5
+#define I_RADIO_CHECKED_DISABLED    6
+#define I_RADIO_UNCHECKED_DISABLED  7
+
+#define PREDEFINED_ICON_COUNT       8
+
+// definition of icon stock
+static ADVANCED_ICON *  s_AdvancedIcons         = NULL;
+static INT              s_AdvancedIconCount     = 0;
+static HIMAGELIST       s_hImageList            = NULL;
+
+static INT
+Advanced_FindIcon(LPCWSTR pszPath, UINT nIconIndex)
+{
+    for (INT i = PREDEFINED_ICON_COUNT; i < s_AdvancedIconCount; ++i)
+    {
+        ADVANCED_ICON *pIcon = &s_AdvancedIcons[i];
+        if (pIcon->nIconIndex == nIconIndex &&
+            lstrcmpiW(pIcon->szPath, pszPath) == 0)
+        {
+            return i;   // icon ID
+        }
+    }
+    return -1;  // not found
+}
+
+static INT
+Advanced_AddIcon(LPCWSTR pszPath, UINT nIconIndex)
+{
+    ADVANCED_ICON *pAllocated;
+
+    // return the ID if already existed
+    INT nIconID = Advanced_FindIcon(pszPath, nIconIndex);
+    if (nIconID != -1)
+        return nIconID;     // already exists
+
+    // extract a small icon
+    HICON hIconSmall = NULL;
+    ExtractIconExW(pszPath, nIconIndex, NULL, &hIconSmall, 1);
+    if (hIconSmall == NULL)
+        return -1;      // failure
+
+    // resize s_AdvancedIcons
+    size_t Size = (s_AdvancedIconCount + 1) * sizeof(ADVANCED_ICON);
+    pAllocated = (ADVANCED_ICON *)realloc(s_AdvancedIcons, Size);
+    if (pAllocated == NULL)
+        return -1;      // failure
+    else
+        s_AdvancedIcons = pAllocated;
+
+    // save icon information
+    ADVANCED_ICON *pIcon = &s_AdvancedIcons[s_AdvancedIconCount];
+    lstrcpynW(pIcon->szPath, pszPath, _countof(pIcon->szPath));
+    pIcon->nIconIndex = nIconIndex;
+
+    // add the icon to the image list
+    ImageList_AddIcon(s_hImageList, hIconSmall);
+
+    // increment the counter
+    nIconID = s_AdvancedIconCount;
+    ++s_AdvancedIconCount;
+
+    DestroyIcon(hIconSmall);
+
+    return nIconID;     // newly-added icon ID
+}
+
+// types of Advanced Setting entry
+typedef enum ADVANCED_ENTRY_TYPE
+{
+    AETYPE_GROUP,
+    AETYPE_CHECKBOX,
+    AETYPE_RADIO,
+} ADVANCED_ENTRY_TYPE;
+
+// an entry info of Advanced Settings
+typedef struct ADVANCED_ENTRY
+{
+    DWORD   dwID;                   // entry ID
+    DWORD   dwParentID;             // parent entry ID
+    DWORD   dwResourceID;           // resource ID
+    WCHAR   szKeyName[64];          // entry key name
+    DWORD   dwType;                 // ADVANCED_ENTRY_TYPE
+    WCHAR   szText[MAX_PATH];       // text
+    INT     nIconID;                // icon ID (See ADVANCED_ICON)
+
+    HKEY    hkeyRoot;               // registry root key
+    WCHAR   szRegPath[MAX_PATH];    // registry path
+    WCHAR   szValueName[64];        // registry value name
+
+    DWORD   dwCheckedValue;         // checked value
+    DWORD   dwUncheckedValue;       // unchecked value
+    DWORD   dwDefaultValue;         // defalut value
+    BOOL    bHasUncheckedValue;     // If FALSE, UncheckedValue is invalid
+
+    HTREEITEM   hItem;              // for TreeView
+    BOOL        bGrayed;            // disabled?
+    BOOL        bChecked;           // checked?
+} ADVANCED_ENTRY, *PADVANCED_ENTRY;
+
+// definition of advanced entries
+static ADVANCED_ENTRY *     s_Advanced = NULL;
+static INT                  s_AdvancedCount = 0;
+
+static HBITMAP
+Create24BppBitmap(HDC hDC, INT cx, INT cy)
+{
+    BITMAPINFO bi;
+    LPVOID pvBits;
+
+    ZeroMemory(&bi, sizeof(bi));
+    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    bi.bmiHeader.biWidth = cx;
+    bi.bmiHeader.biHeight = cy;
+    bi.bmiHeader.biPlanes = 1;
+    bi.bmiHeader.biBitCount = 24;
+    bi.bmiHeader.biCompression = BI_RGB;
+
+    HBITMAP hbm = CreateDIBSection(hDC, &bi, DIB_RGB_COLORS, &pvBits, NULL, 0);
+    return hbm;
+}
+
+static HBITMAP
+CreateCheckImage(HDC hDC, BOOL bCheck, BOOL bEnabled = TRUE)
+{
+    INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
+    INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
+
+    HBITMAP hbm = Create24BppBitmap(hDC, cxSmallIcon, cySmallIcon);
+    if (hbm == NULL)
+        return NULL;    // failure
+
+    RECT Rect, BoxRect;
+    SetRect(&Rect, 0, 0, cxSmallIcon, cySmallIcon);
+    BoxRect = Rect;
+    InflateRect(&BoxRect, -1, -1);
+
+    HGDIOBJ hbmOld = SelectObject(hDC, hbm);
+    {
+        UINT uState = DFCS_BUTTONCHECK | DFCS_FLAT | DFCS_MONO;
+        if (bCheck)
+            uState |= DFCS_CHECKED;
+        if (!bEnabled)
+            uState |= DFCS_INACTIVE;
+        DrawFrameControl(hDC, &BoxRect, DFC_BUTTON, uState);
+    }
+    SelectObject(hDC, hbmOld);
+
+    return hbm;     // success
+}
+
+static HBITMAP
+CreateCheckMask(HDC hDC)
+{
+    INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
+    INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
+
+    HBITMAP hbm = CreateBitmap(cxSmallIcon, cySmallIcon, 1, 1, NULL);
+    if (hbm == NULL)
+        return NULL;    // failure
+
+    RECT Rect, BoxRect;
+    SetRect(&Rect, 0, 0, cxSmallIcon, cySmallIcon);
+    BoxRect = Rect;
+    InflateRect(&BoxRect, -1, -1);
+
+    HGDIOBJ hbmOld = SelectObject(hDC, hbm);
+    {
+        FillRect(hDC, &Rect, HBRUSH(GetStockObject(WHITE_BRUSH)));
+        FillRect(hDC, &BoxRect, HBRUSH(GetStockObject(BLACK_BRUSH)));
+    }
+    SelectObject(hDC, hbmOld);
+
+    return hbm;     // success
+}
+
+static HBITMAP
+CreateRadioImage(HDC hDC, BOOL bCheck, BOOL bEnabled = TRUE)
+{
+    INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
+    INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
+
+    HBITMAP hbm = Create24BppBitmap(hDC, cxSmallIcon, cySmallIcon);
+    if (hbm == NULL)
+        return NULL;    // failure
+
+    RECT Rect, BoxRect;
+    SetRect(&Rect, 0, 0, cxSmallIcon, cySmallIcon);
+    BoxRect = Rect;
+    InflateRect(&BoxRect, -1, -1);
+
+    HGDIOBJ hbmOld = SelectObject(hDC, hbm);
+    {
+        UINT uState = DFCS_BUTTONRADIOIMAGE | DFCS_FLAT | DFCS_MONO;
+        if (bCheck)
+            uState |= DFCS_CHECKED;
+        if (!bEnabled)
+            uState |= DFCS_INACTIVE;
+        DrawFrameControl(hDC, &BoxRect, DFC_BUTTON, uState);
+    }
+    SelectObject(hDC, hbmOld);
+
+    return hbm;     // success
+}
+
+static HBITMAP
+CreateRadioMask(HDC hDC)
+{
+    INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
+    INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
+
+    HBITMAP hbm = CreateBitmap(cxSmallIcon, cySmallIcon, 1, 1, NULL);
+    if (hbm == NULL)
+        return NULL;    // failure
+
+    RECT Rect, BoxRect;
+    SetRect(&Rect, 0, 0, cxSmallIcon, cySmallIcon);
+    BoxRect = Rect;
+    InflateRect(&BoxRect, -1, -1);
+
+    HGDIOBJ hbmOld = SelectObject(hDC, hbm);
+    {
+        FillRect(hDC, &Rect, HBRUSH(GetStockObject(WHITE_BRUSH)));
+        UINT uState = DFCS_BUTTONRADIOMASK | DFCS_FLAT | DFCS_MONO;
+        DrawFrameControl(hDC, &BoxRect, DFC_BUTTON, uState);
+    }
+    SelectObject(hDC, hbmOld);
+
+    return hbm;     // success
+}
+
+static HIMAGELIST
+CreateTreeImageList(VOID)
+{
+    HIMAGELIST hImageList;
+    hImageList = ImageList_Create(16, 16, ILC_COLOR24 | ILC_MASK, 9, 1);
+    if (hImageList == NULL)
+        return NULL;    // failure
+
+    // free if existed
+    if (s_AdvancedIcons)
+    {
+        free(s_AdvancedIcons);
+        s_AdvancedIcons = NULL;
+    }
+    s_AdvancedIconCount = 0;
+
+    // allocate now
+    ADVANCED_ICON *pAllocated;
+    size_t Size = PREDEFINED_ICON_COUNT * sizeof(ADVANCED_ICON);
+    pAllocated = (ADVANCED_ICON *)calloc(1, Size);
+    if (pAllocated == NULL)
+        return NULL;    // failure
+
+    s_AdvancedIconCount = PREDEFINED_ICON_COUNT;
+    s_AdvancedIcons = pAllocated;
+
+    // add the predefined icons
+
+    HDC hDC = CreateCompatibleDC(NULL);
+    HBITMAP hbmMask = CreateCheckMask(hDC);
+
+    HBITMAP hbmChecked, hbmUnchecked;
+
+    hbmChecked = CreateCheckImage(hDC, TRUE);
+    ImageList_Add(hImageList, hbmChecked, hbmMask);
+    DeleteObject(hbmChecked);
+
+    hbmUnchecked = CreateCheckImage(hDC, FALSE);
+    ImageList_Add(hImageList, hbmUnchecked, hbmMask);
+    DeleteObject(hbmUnchecked);
+
+    hbmChecked = CreateCheckImage(hDC, TRUE, FALSE);
+    ImageList_Add(hImageList, hbmChecked, hbmMask);
+    DeleteObject(hbmChecked);
+
+    hbmUnchecked = CreateCheckImage(hDC, FALSE, FALSE);
+    ImageList_Add(hImageList, hbmUnchecked, hbmMask);
+    DeleteObject(hbmUnchecked);
+
+    DeleteObject(hbmMask);
+    hbmMask = CreateRadioMask(hDC);
+
+    hbmChecked = CreateRadioImage(hDC, TRUE);
+    ImageList_Add(hImageList, hbmChecked, hbmMask);
+    DeleteObject(hbmChecked);
+
+    hbmUnchecked = CreateRadioImage(hDC, FALSE);
+    ImageList_Add(hImageList, hbmUnchecked, hbmMask);
+    DeleteObject(hbmUnchecked);
+
+    hbmChecked = CreateRadioImage(hDC, TRUE, FALSE);
+    ImageList_Add(hImageList, hbmChecked, hbmMask);
+    DeleteObject(hbmChecked);
+
+    hbmUnchecked = CreateRadioImage(hDC, FALSE, FALSE);
+    ImageList_Add(hImageList, hbmUnchecked, hbmMask);
+    DeleteObject(hbmUnchecked);
+
+    DeleteObject(hbmMask);
+
+    return hImageList;
+}
+
+static ADVANCED_ENTRY *
+Advanced_GetItem(DWORD dwID)
+{
+    if (dwID == DWORD(-1))
+        return NULL;
+
+    for (INT i = 0; i < s_AdvancedCount; ++i)
+    {
+        ADVANCED_ENTRY *pEntry = &s_Advanced[i];
+        if (pEntry->dwID == dwID)
+            return pEntry;
+    }
+    return NULL;    // failure
+}
+
+static INT
+Advanced_GetImage(ADVANCED_ENTRY *pEntry)
+{
+    switch (pEntry->dwType)
+    {
+        case AETYPE_GROUP:
+            return pEntry->nIconID;
+
+        case AETYPE_CHECKBOX:
+            if (pEntry->bGrayed)
+            {
+                if (pEntry->bChecked)
+                    return I_CHECKED_DISABLED;
+                else
+                    return I_UNCHECKED_DISABLED;
+            }
+            else
+            {
+                if (pEntry->bChecked)
+                    return I_CHECKED;
+                else
+                    return I_UNCHECKED;
+            }
+
+        case AETYPE_RADIO:
+            if (pEntry->bGrayed)
+            {
+                if (pEntry->bChecked)
+                    return I_RADIO_CHECKED_DISABLED;
+                else
+                    return I_RADIO_UNCHECKED_DISABLED;
+            }
+            else
+            {
+                if (pEntry->bChecked)
+                    return I_RADIO_CHECKED;
+                else
+                    return I_RADIO_UNCHECKED;
+            }
+    }
+    return -1;  // failure
+}
+
+static VOID
+Advanced_InsertEntry(HWND hwndTreeView, ADVANCED_ENTRY *pEntry)
+{
+    ADVANCED_ENTRY *pParent = Advanced_GetItem(pEntry->dwParentID);
+    HTREEITEM hParent = TVI_ROOT;
+    if (pParent)
+        hParent = pParent->hItem;
+
+    TV_INSERTSTRUCT Insertion;
+    ZeroMemory(&Insertion, sizeof(Insertion));
+    Insertion.hParent = hParent;
+    Insertion.hInsertAfter = TVI_LAST;
+    Insertion.item.mask =
+        TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
+    Insertion.item.pszText = pEntry->szText;
+
+    INT iImage = Advanced_GetImage(pEntry);
+    Insertion.item.iImage = Insertion.item.iSelectedImage = iImage;
+    Insertion.item.lParam = pEntry->dwID;
+    pEntry->hItem = TreeView_InsertItem(hwndTreeView, &Insertion);
+}
+
+static VOID
+Advanced_InsertAll(HWND hwndTreeView)
+{
+    TreeView_DeleteAllItems(hwndTreeView);
+
+    // insert the entries
+    ADVANCED_ENTRY *pEntry;
+    for (INT i = 0; i < s_AdvancedCount; ++i)
+    {
+        pEntry = &s_Advanced[i];
+        Advanced_InsertEntry(hwndTreeView, pEntry);
+    }
+
+    // expand all
+    for (INT i = 0; i < s_AdvancedCount; ++i)
+    {
+        pEntry = &s_Advanced[i];
+        if (pEntry->dwType == AETYPE_GROUP)
+        {
+            TreeView_Expand(hwndTreeView, pEntry->hItem, TVE_EXPAND);
+        }
+    }
+}
+
+static BOOL
+Advanced_LoadTree(HKEY hKey, LPCWSTR pszKeyName, DWORD dwParentID)
+{
+    DWORD dwIndex;
+    WCHAR szKeyName[64], szText[MAX_PATH], *pch;
+    DWORD Size, Value;
+    ADVANCED_ENTRY *pAllocated;
+
+    // resize s_Advanced
+    Size = (s_AdvancedCount + 1) * sizeof(ADVANCED_ENTRY);
+    pAllocated = (ADVANCED_ENTRY *)realloc(s_Advanced, Size);
+    if (pAllocated == NULL)
+        return FALSE;   // failure
+    else
+        s_Advanced = pAllocated;
+
+    ADVANCED_ENTRY *pEntry = &s_Advanced[s_AdvancedCount];
+
+    // dwID, dwParentID, szKeyName
+    pEntry->dwID = s_AdvancedCount;
+    pEntry->dwParentID = dwParentID;
+    lstrcpynW(pEntry->szKeyName, pszKeyName, _countof(pEntry->szKeyName));
+
+    // Text, ResourceID
+    pEntry->szText[0] = 0;
+    pEntry->dwResourceID = 0;
+    szText[0] = 0;
+    Size = sizeof(szText);
+    RegQueryValueExW(hKey, L"Text", NULL, NULL, LPBYTE(szText), &Size);
+    if (szText[0] == L'@')
+    {
+        pch = wcsrchr(szText, L',');
+        if (pch)
+        {
+            *pch = 0;
+            dwIndex = abs(_wtoi(pch + 1));
+            pEntry->dwResourceID = dwIndex;
+        }
+        HINSTANCE hInst = LoadLibraryW(&szText[1]);
+        LoadStringW(hInst, dwIndex, szText, _countof(szText));
+        FreeLibrary(hInst);
+    }
+    else
+    {
+        pEntry->dwResourceID = DWORD(-1);
+    }
+    lstrcpynW(pEntry->szText, szText, _countof(pEntry->szText));
+
+    // Type
+    szText[0] = 0;
+    RegQueryValueExW(hKey, L"Type", NULL, NULL, LPBYTE(szText), &Size);
+    if (lstrcmpiW(szText, L"checkbox") == 0)
+        pEntry->dwType = AETYPE_CHECKBOX;
+    else if (lstrcmpiW(szText, L"radio") == 0)
+        pEntry->dwType = AETYPE_RADIO;
+    else if (lstrcmpiW(szText, L"group") == 0)
+        pEntry->dwType = AETYPE_GROUP;
+    else
+        return FALSE;   // failure
+
+    pEntry->nIconID = -1;
+    if (pEntry->dwType == AETYPE_GROUP)
+    {
+        // Bitmap (Icon)
+        UINT nIconIndex = 0;
+        Size = sizeof(szText);
+        szText[0] = 0;
+        RegQueryValueExW(hKey, L"Bitmap", NULL, NULL, LPBYTE(szText), &Size);
+
+        WCHAR szExpanded[MAX_PATH];
+        ExpandEnvironmentStringsW(szText, szExpanded, _countof(szExpanded));
+        pch = wcsrchr(szExpanded, L',');
+        if (pch)
+        {
+            *pch = 0;
+            nIconIndex = abs(_wtoi(pch + 1));
+        }
+        pEntry->nIconID = Advanced_AddIcon(szExpanded, nIconIndex);
+    }
+
+    if (pEntry->dwType == AETYPE_GROUP)
+    {
+        pEntry->hkeyRoot = NULL;
+        pEntry->szRegPath[0] = 0;
+        pEntry->szValueName[0] = 0;
+        pEntry->dwCheckedValue = 0;
+        pEntry->bHasUncheckedValue = FALSE;
+        pEntry->dwUncheckedValue = 0;
+        pEntry->dwDefaultValue = 0;
+        pEntry->hItem = NULL;
+        pEntry->bGrayed = FALSE;
+        pEntry->bChecked = FALSE;
+    }
+    else
+    {
+        // HKeyRoot
+        Value = DWORD(HKEY_CURRENT_USER);
+        Size = sizeof(Value);
+        RegQueryValueExW(hKey, L"HKeyRoot", NULL, NULL, LPBYTE(&Value), &Size);
+        pEntry->hkeyRoot = HKEY(Value);
+
+        // RegPath
+        pEntry->szRegPath[0] = 0;
+        Size = sizeof(szText);
+        RegQueryValueExW(hKey, L"RegPath", NULL, NULL, LPBYTE(szText), &Size);
+        lstrcpynW(pEntry->szRegPath, szText, _countof(pEntry->szRegPath));
+
+        // ValueName
+        pEntry->szValueName[0] = 0;
+        Size = sizeof(szText);
+        RegQueryValueExW(hKey, L"ValueName", NULL, NULL, LPBYTE(szText), &Size);
+        lstrcpynW(pEntry->szValueName, szText, _countof(pEntry->szValueName));
+
+        // CheckedValue
+        Size = sizeof(Value);
+        Value = 0x00000001;
+        RegQueryValueExW(hKey, L"CheckedValue", NULL, NULL, LPBYTE(&Value), &Size);
+        pEntry->dwCheckedValue = Value;
+
+        // UncheckedValue
+        Size = sizeof(Value);
+        Value = 0x00000000;
+        pEntry->bHasUncheckedValue = TRUE;
+        if (RegQueryValueExW(hKey, L"UncheckedValue", NULL,
+                             NULL, LPBYTE(&Value), &Size) != ERROR_SUCCESS)
+        {
+            pEntry->bHasUncheckedValue = FALSE;
+        }
+        pEntry->dwUncheckedValue = Value;
+
+        // DefaultValue
+        Size = sizeof(Value);
+        Value = 0x00000001;
+        RegQueryValueExW(hKey, L"DefaultValue", NULL, NULL, LPBYTE(&Value), &Size);
+        pEntry->dwDefaultValue = Value;
+
+        // hItem
+        pEntry->hItem = NULL;
+
+        // bGrayed, bChecked
+        HKEY hkeyTarget;
+        Value = pEntry->dwDefaultValue;
+        pEntry->bGrayed = TRUE;
+        if (RegOpenKeyExW(HKEY(pEntry->hkeyRoot), pEntry->szRegPath, 0,
+                          KEY_READ, &hkeyTarget) == ERROR_SUCCESS)
+        {
+            Size = sizeof(Value);
+            if (RegQueryValueExW(hkeyTarget, pEntry->szValueName, NULL, NULL,
+                                 LPBYTE(&Value), &Size) == ERROR_SUCCESS)
+            {
+                pEntry->bGrayed = FALSE;
+            }
+            RegCloseKey(hkeyTarget);
+        }
+        pEntry->bChecked = (Value == pEntry->dwCheckedValue);
+    }
+
+    // Grayed (ReactOS extension)
+    Size = sizeof(Value);
+    Value = FALSE;
+    RegQueryValueExW(hKey, L"Grayed", NULL, NULL, LPBYTE(&Value), &Size);
+    if (!pEntry->bGrayed)
+        pEntry->bGrayed = Value;
+
+    BOOL bIsGroup = (pEntry->dwType == AETYPE_GROUP);
+    dwParentID = pEntry->dwID;
+    ++s_AdvancedCount;
+
+    if (!bIsGroup)
+        return TRUE;    // success
+
+    // load the children
+    dwIndex = 0;
+    while (RegEnumKeyW(hKey, dwIndex, szKeyName,
+                       _countof(szKeyName)) == ERROR_SUCCESS)
+    {
+        HKEY hkeyChild;
+        if (RegOpenKeyExW(hKey, szKeyName, 0, KEY_READ,
+                          &hkeyChild) != ERROR_SUCCESS)
+        {
+            ++dwIndex;
+            continue;   // failure
+        }
+
+        Advanced_LoadTree(hkeyChild, szKeyName, dwParentID);
+        RegCloseKey(hkeyChild);
+
+        ++dwIndex;
+    }
+
+    return TRUE;    // success
+}
+
+static BOOL
+Advanced_LoadAll(VOID)
+{
+    static const WCHAR s_szAdvanced[] =
+        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced";
+
+    // free if already existed
+    if (s_Advanced)
+    {
+        free(s_Advanced);
+        s_Advanced = NULL;
+    }
+    s_AdvancedCount = 0;
+
+    HKEY hKey;
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szAdvanced, 0,
+                      KEY_READ, &hKey) != ERROR_SUCCESS)
+    {
+        return FALSE;   // failure
+    }
+
+    // load the children
+    WCHAR szKeyName[64];
+    DWORD dwIndex = 0;
+    while (RegEnumKeyW(hKey, dwIndex, szKeyName,
+                       _countof(szKeyName)) == ERROR_SUCCESS)
+    {
+        HKEY hkeyChild;
+        if (RegOpenKeyExW(hKey, szKeyName, 0, KEY_READ,
+                          &hkeyChild) != ERROR_SUCCESS)
+        {
+            ++dwIndex;
+            continue;   // failure
+        }
+
+        Advanced_LoadTree(hkeyChild, szKeyName, DWORD(-1));
+        RegCloseKey(hkeyChild);
+
+        ++dwIndex;
+    }
+
+    RegCloseKey(hKey);
+
+    return TRUE;    // success
+}
+
+static int
+Advanced_Compare(const void *x, const void *y)
+{
+    ADVANCED_ENTRY *pEntry1 = (ADVANCED_ENTRY *)x;
+    ADVANCED_ENTRY *pEntry2 = (ADVANCED_ENTRY *)y;
+
+    DWORD dwParentID1 = pEntry1->dwParentID;
+    DWORD dwParentID2 = pEntry2->dwParentID;
+
+    if (dwParentID1 == dwParentID2)
+        return lstrcmpi(pEntry1->szText, pEntry2->szText);
+
+    DWORD i, m, n;
+    const UINT MAX_DEPTH = 32;
+    ADVANCED_ENTRY *pArray1[MAX_DEPTH];
+    ADVANCED_ENTRY *pArray2[MAX_DEPTH];
+
+    // Make ancestor lists
+    for (i = m = n = 0; i < MAX_DEPTH; ++i)
+    {
+        ADVANCED_ENTRY *pParent1 = Advanced_GetItem(dwParentID1);
+        ADVANCED_ENTRY *pParent2 = Advanced_GetItem(dwParentID2);
+        if (!pParent1 && !pParent2)
+            break;
+
+        if (pParent1)
+        {
+            pArray1[m++] = pParent1;
+            dwParentID1 = pParent1->dwParentID;
+        }
+        if (pParent2)
+        {
+            pArray2[n++] = pParent2;
+            dwParentID2 = pParent2->dwParentID;
+        }
+    }
+
+    UINT k = min(m, n);
+    for (i = 0; i < k; ++i)
+    {
+        INT nCompare = lstrcmpi(pArray1[m - i - 1]->szText, pArray2[n - i - 1]->szText);
+        if (nCompare < 0)
+            return -1;
+        if (nCompare > 0)
+            return 1;
+    }
+
+    if (m < n)
+        return -1;
+    if (m > n)
+        return 1;
+    return lstrcmpi(pEntry1->szText, pEntry2->szText);
+}
+
+static VOID
+Advanced_SortAll(VOID)
+{
+    qsort(s_Advanced, s_AdvancedCount, sizeof(ADVANCED_ENTRY), Advanced_Compare);
+}
 
 EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
 
-static
+static VOID
+UpdateGeneralIcons(HWND hDlg)
+{
+    HWND hwndTaskIcon, hwndFolderIcon, hwndClickIcon;
+    HICON hTaskIcon = NULL, hFolderIcon = NULL, hClickIcon = NULL;
+    LPTSTR lpTaskIconName = NULL, lpFolderIconName = NULL, lpClickIconName = NULL;
+
+    // show task setting icon
+    if(IsDlgButtonChecked(hDlg, IDC_FOLDER_OPTIONS_COMMONTASKS) == BST_CHECKED)
+        lpTaskIconName = MAKEINTRESOURCE(IDI_SHELL_SHOW_COMMON_TASKS);
+    else if(IsDlgButtonChecked(hDlg, IDC_FOLDER_OPTIONS_CLASSICFOLDERS) == BST_CHECKED)
+        lpTaskIconName = MAKEINTRESOURCE(IDI_SHELL_CLASSIC_FOLDERS);
+
+    if (lpTaskIconName)
+    {
+        hTaskIcon = (HICON)LoadImage(shell32_hInstance,
+                                              lpTaskIconName,
+                                              IMAGE_ICON,
+                                              0,
+                                              0,
+                                              LR_DEFAULTCOLOR);
+        if (hTaskIcon)
+        {
+            hwndTaskIcon = GetDlgItem(hDlg,
+                                    IDC_FOLDER_OPTIONS_TASKICON);
+            if (hwndTaskIcon)
+            {
+                SendMessage(hwndTaskIcon,
+                            STM_SETIMAGE,
+                            IMAGE_ICON,
+                            (LPARAM)hTaskIcon);
+            }
+        }
+    }
+    
+    // show Folder setting icons
+    if(IsDlgButtonChecked(hDlg, IDC_FOLDER_OPTIONS_SAMEWINDOW) == BST_CHECKED)
+        lpFolderIconName = MAKEINTRESOURCE(IDI_SHELL_OPEN_IN_SOME_WINDOW);
+    else if(IsDlgButtonChecked(hDlg, IDC_FOLDER_OPTIONS_OWNWINDOW) == BST_CHECKED)
+        lpFolderIconName = MAKEINTRESOURCE(IDI_SHELL_OPEN_IN_NEW_WINDOW);
+    
+    if (lpFolderIconName)
+    {
+        hFolderIcon = (HICON)LoadImage(shell32_hInstance,
+                                              lpFolderIconName,
+                                              IMAGE_ICON,
+                                              0,
+                                              0,
+                                              LR_DEFAULTCOLOR);
+        if (hFolderIcon)
+        {
+            hwndFolderIcon = GetDlgItem(hDlg,
+                                    IDC_FOLDER_OPTIONS_FOLDERICON);
+            if (hwndFolderIcon)
+            {
+                SendMessage(hwndFolderIcon,
+                            STM_SETIMAGE,
+                            IMAGE_ICON,
+                            (LPARAM)hFolderIcon);
+            }
+        }
+    }
+
+    // Show click setting icon
+    if(IsDlgButtonChecked(hDlg, IDC_FOLDER_OPTIONS_SINGLECLICK) == BST_CHECKED)
+        lpClickIconName = MAKEINTRESOURCE(IDI_SHELL_SINGLE_CLICK_TO_OPEN);
+    else if(IsDlgButtonChecked(hDlg, IDC_FOLDER_OPTIONS_DOUBLECLICK) == BST_CHECKED)
+        lpClickIconName = MAKEINTRESOURCE(IDI_SHELL_DOUBLE_CLICK_TO_OPEN);
+
+    if (lpClickIconName)
+    {
+        hClickIcon = (HICON)LoadImage(shell32_hInstance,
+                                              lpClickIconName,
+                                              IMAGE_ICON,
+                                              0,
+                                              0,
+                                              LR_DEFAULTCOLOR);
+        if (hClickIcon)
+        {
+            hwndClickIcon = GetDlgItem(hDlg,
+                                    IDC_FOLDER_OPTIONS_CLICKICON);
+            if (hwndClickIcon)
+            {
+                SendMessage(hwndClickIcon,
+                            STM_SETIMAGE,
+                            IMAGE_ICON,
+                            (LPARAM)hClickIcon);
+            }
+        }
+    }
+
+    // Clean up
+    if(hTaskIcon)
+        DeleteObject(hTaskIcon);
+    if(hFolderIcon)
+        DeleteObject(hFolderIcon);
+    if(hClickIcon)
+        DeleteObject(hClickIcon);
+    
+    return;
+}
+
 INT_PTR
 CALLBACK
 FolderOptionsGeneralDlg(
@@ -93,56 +872,420 @@ FolderOptionsGeneralDlg(
     LPARAM lParam
 )
 {
+    switch(uMsg)
+    {
+        case WM_INITDIALOG:
+            // FIXME
+            break;
+            
+        case WM_COMMAND:
+            switch (LOWORD(wParam))
+            {
+                case IDC_FOLDER_OPTIONS_COMMONTASKS:
+                case IDC_FOLDER_OPTIONS_CLASSICFOLDERS:
+                case IDC_FOLDER_OPTIONS_SAMEWINDOW:
+                case IDC_FOLDER_OPTIONS_OWNWINDOW:
+                case IDC_FOLDER_OPTIONS_SINGLECLICK:
+                case IDC_FOLDER_OPTIONS_DOUBLECLICK:
+                    if (HIWORD(wParam) == BN_CLICKED)
+                    {
+                        UpdateGeneralIcons(hwndDlg);
+
+                        /* Enable the 'Apply' button */
+                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    }
+                    break;
+            }
+            break;
+
+        case WM_NOTIFY:
+        {
+            LPNMHDR pnmh = (LPNMHDR)lParam;
+
+            switch (pnmh->code)
+            {
+                case PSN_SETACTIVE:
+                    break;
+
+                case PSN_APPLY:
+                    break;
+            }
+            break;
+        }
+        
+        case WM_DESTROY:
+            break;
+         
+         default: 
+             return FALSE;
+    }
     return FALSE;
 }
 
-static
-VOID
-InitializeFolderOptionsListCtrl(HWND hwndDlg)
+static BOOL
+ViewDlg_OnInitDialog(HWND hwndDlg)
 {
-    RECT clientRect;
-    LVCOLUMNW col;
-    WCHAR szName[50];
-    HWND hDlgCtrl;
+    HWND hwndTreeView = GetDlgItem(hwndDlg, 14003);
 
-    hDlgCtrl = GetDlgItem(hwndDlg, 14003);
+    s_hImageList = CreateTreeImageList();
+    TreeView_SetImageList(hwndTreeView, s_hImageList, TVSIL_NORMAL);
 
-    if (!LoadStringW(shell32_hInstance, IDS_COLUMN_EXTENSION, szName, sizeof(szName) / sizeof(WCHAR)))
-        szName[0] = 0;
-    szName[(sizeof(szName)/sizeof(WCHAR))-1] = 0;
+    Advanced_LoadAll();
+    Advanced_SortAll();
+    Advanced_InsertAll(hwndTreeView);
 
-    GetClientRect(hDlgCtrl, &clientRect);
-    ZeroMemory(&col, sizeof(LV_COLUMN));
-    col.mask      = LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
-    col.iSubItem  = 0;
-    col.pszText = szName;
-    col.fmt = LVCFMT_LEFT;
-    col.cx        = (clientRect.right - clientRect.left) - GetSystemMetrics(SM_CXVSCROLL);
-    (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMN, 0, (LPARAM)&col);
+    return TRUE;    // set focus
+}
 
+static BOOL
+ViewDlg_ToggleCheckItem(HWND hwndDlg, HTREEITEM hItem)
+{
+    HWND hwndTreeView = GetDlgItem(hwndDlg, 14003);
+
+    // get the item
+    TV_ITEM Item;
+    INT i;
+    ZeroMemory(&Item, sizeof(Item));
+    Item.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_PARAM;
+    Item.hItem = hItem;
+    if (!TreeView_GetItem(hwndTreeView, &Item))
+        return FALSE;       // no such item
+
+    ADVANCED_ENTRY *pEntry = Advanced_GetItem(Item.lParam);
+    if (pEntry == NULL)
+        return FALSE;       // no such item
+    if (pEntry->bGrayed)
+        return FALSE;       // disabled
+
+    // toggle check mark
+    Item.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+    switch (pEntry->dwType)
+    {
+        case AETYPE_CHECKBOX:
+            pEntry->bChecked = !pEntry->bChecked;
+            break;
+        case AETYPE_RADIO:
+            // reset all the entries of the same parent
+            for (i = 0; i < s_AdvancedCount; ++i)
+            {
+                ADVANCED_ENTRY *pEntry2 = &s_Advanced[i];
+                if (pEntry->dwParentID == pEntry2->dwParentID)
+                {
+                    pEntry2->bChecked = FALSE;
 
+                    Item.hItem = pEntry2->hItem;
+                    INT iImage = Advanced_GetImage(pEntry2);
+                    Item.iImage = Item.iSelectedImage = iImage;
+                    TreeView_SetItem(hwndTreeView, &Item);
+                }
+            }
+            pEntry->bChecked = TRUE;
+            break;
+        default:
+            return FALSE;   // failure
+    }
+    Item.iImage = Item.iSelectedImage = Advanced_GetImage(pEntry);
+    Item.hItem = hItem;
+    TreeView_SetItem(hwndTreeView, &Item);
+
+    // redraw the item
+    RECT rcItem;
+    TreeView_GetItemRect(hwndTreeView, hItem, &rcItem, FALSE);
+    InvalidateRect(hwndTreeView, &rcItem, TRUE);
+    return TRUE;    // success
+}
 
+static VOID
+ViewDlg_OnTreeViewClick(HWND hwndDlg)
+{
+    HWND hwndTreeView = GetDlgItem(hwndDlg, 14003);
+
+    // do hit test to get the clicked item
+    TV_HITTESTINFO HitTest;
+    ZeroMemory(&HitTest, sizeof(HitTest));
+    DWORD dwPos = GetMessagePos();
+    HitTest.pt.x = LOWORD(dwPos);
+    HitTest.pt.y = HIWORD(dwPos);
+    ScreenToClient(hwndTreeView, &HitTest.pt);
+    HTREEITEM hItem = TreeView_HitTest(hwndTreeView, &HitTest);
+
+    // toggle the check mark if possible
+    if (ViewDlg_ToggleCheckItem(hwndDlg, hItem))
+    {
+        // property sheet was changed
+        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+    }
 }
 
-static
-INT_PTR
-CALLBACK
+static void
+ViewDlg_OnTreeViewKeyDown(HWND hwndDlg, TV_KEYDOWN *KeyDown)
+{
+    HWND hwndTreeView = GetDlgItem(hwndDlg, 14003);
+
+    if (KeyDown->wVKey == VK_SPACE)
+    {
+        // [Space] key was pressed
+        HTREEITEM hItem = TreeView_GetSelection(hwndTreeView);
+        if (ViewDlg_ToggleCheckItem(hwndDlg, hItem))
+        {
+            PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+        }
+    }
+}
+
+static INT_PTR
+ViewDlg_OnTreeCustomDraw(HWND hwndDlg, NMTVCUSTOMDRAW *Draw)
+{
+    NMCUSTOMDRAW& nmcd = Draw->nmcd;
+    switch (nmcd.dwDrawStage)
+    {
+        case CDDS_PREPAINT:
+            return CDRF_NOTIFYITEMDRAW;     // for CDDS_ITEMPREPAINT
+
+        case CDDS_ITEMPREPAINT:
+            if (!(nmcd.uItemState & CDIS_SELECTED)) // not selected
+            {
+                LPARAM lParam = nmcd.lItemlParam;
+                ADVANCED_ENTRY *pEntry = Advanced_GetItem(lParam);
+                if (pEntry && pEntry->bGrayed) // disabled
+                {
+                    // draw as grayed
+                    Draw->clrText = GetSysColor(COLOR_GRAYTEXT);
+                    Draw->clrTextBk = GetSysColor(COLOR_WINDOW);
+                    return CDRF_NEWFONT;
+                }
+            }
+            break;
+
+        default:
+            break;
+    }
+    return CDRF_DODEFAULT;
+}
+
+static VOID
+Advanced_RestoreDefaults(HWND hwndDlg)
+{
+    HWND hwndTreeView = GetDlgItem(hwndDlg, 14003);
+
+    for (INT i = 0; i < s_AdvancedCount; ++i)
+    {
+        // ignore if the type is group
+        ADVANCED_ENTRY *pEntry = &s_Advanced[i];
+        if (pEntry->dwType == AETYPE_GROUP)
+            continue;
+
+        // set default value on registry
+        HKEY hKey;
+        if (RegOpenKeyExW(HKEY(pEntry->hkeyRoot), pEntry->szRegPath,
+                          0, KEY_WRITE, &hKey) != ERROR_SUCCESS)
+        {
+            continue;
+        }
+        RegSetValueExW(hKey, pEntry->szValueName, 0, REG_DWORD,
+                       LPBYTE(pEntry->dwDefaultValue), sizeof(DWORD));
+        RegCloseKey(hKey);
+
+        // update check status
+        pEntry->bChecked = (pEntry->dwCheckedValue == pEntry->dwDefaultValue);
+
+        // update the image
+        TV_ITEM Item;
+        ZeroMemory(&Item, sizeof(Item));
+        Item.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+        Item.hItem = pEntry->hItem;
+        Item.iImage = Item.iSelectedImage = Advanced_GetImage(pEntry);
+        TreeView_SetItem(hwndTreeView, &Item);
+    }
+
+    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+}
+
+/* FIXME: These macros should not be defined here */
+#ifndef SSF_SHOWSUPERHIDDEN
+    #define SSF_SHOWSUPERHIDDEN     0x00040000
+#endif
+#ifndef SSF_SEPPROCESS
+    #define SSF_SEPPROCESS          0x00080000
+#endif
+
+static VOID
+ScanAdvancedSettings(SHELLSTATE *pSS, DWORD *pdwMask)
+{
+    for (INT i = 0; i < s_AdvancedCount; ++i)
+    {
+        const ADVANCED_ENTRY *pEntry = &s_Advanced[i];
+        if (pEntry->dwType == AETYPE_GROUP || pEntry->bGrayed)
+            continue;
+
+        BOOL bChecked = pEntry->bChecked;
+
+        // FIXME: Add more items
+        if (lstrcmpiW(pEntry->szKeyName, L"SuperHidden") == 0)
+        {
+            pSS->fShowSuperHidden = !bChecked ? 1 : 0;
+            *pdwMask |= SSF_SHOWSUPERHIDDEN;
+            continue;
+        }
+        if (lstrcmpiW(pEntry->szKeyName, L"DesktopProcess") == 0)
+        {
+            pSS->fSepProcess = bChecked ? 1 : 0;
+            *pdwMask |= SSF_SEPPROCESS;
+            continue;
+        }
+        if (lstrcmpiW(pEntry->szKeyName, L"SHOWALL") == 0)
+        {
+            pSS->fShowAllObjects = !bChecked ? 1 : 0;
+            *pdwMask |= SSF_SHOWALLOBJECTS;
+            continue;
+        }
+        if (lstrcmpiW(pEntry->szKeyName, L"HideFileExt") == 0)
+        {
+            pSS->fShowExtensions = !bChecked ? 1 : 0;
+            *pdwMask |= SSF_SHOWEXTENSIONS;
+            continue;
+        }
+        if (lstrcmpiW(pEntry->szKeyName, L"ShowCompColor") == 0)
+        {
+            pSS->fShowCompColor = bChecked ? 1 : 0;
+            *pdwMask |= SSF_SHOWCOMPCOLOR;
+            continue;
+        }
+        if (lstrcmpiW(pEntry->szKeyName, L"ShowInfoTip") == 0)
+        {
+            pSS->fShowInfoTip = bChecked ? 1 : 0;
+            *pdwMask |= SSF_SHOWINFOTIP;
+            continue;
+        }
+    }
+}
+
+extern "C"
+VOID WINAPI SHGetSetSettings(LPSHELLSTATE lpss, DWORD dwMask, BOOL bSet);
+
+static BOOL CALLBACK RefreshBrowsersCallback (HWND hWnd, LPARAM msg)
+{
+    WCHAR ClassName[100];
+    if (GetClassName(hWnd, ClassName, 100))
+    {
+        if (!wcscmp(ClassName, L"Progman") || 
+            !wcscmp(ClassName, L"CabinetWClass") ||
+            !wcscmp(ClassName, L"ExploreWClass"))
+        {
+            PostMessage(hWnd, WM_COMMAND, FCIDM_DESKBROWSER_REFRESH, 0);
+        }
+    }
+    return TRUE;
+}
+
+static VOID
+ViewDlg_Apply(HWND hwndDlg)
+{
+    for (INT i = 0; i < s_AdvancedCount; ++i)
+    {
+        // ignore the entry if the type is group or the entry is grayed
+        ADVANCED_ENTRY *pEntry = &s_Advanced[i];
+        if (pEntry->dwType == AETYPE_GROUP || pEntry->bGrayed)
+            continue;
+
+        // open the registry key
+        HKEY hkeyTarget;
+        if (RegOpenKeyExW(HKEY(pEntry->hkeyRoot), pEntry->szRegPath, 0,
+                          KEY_WRITE, &hkeyTarget) != ERROR_SUCCESS)
+        {
+            continue;
+        }
+
+        // checked or unchecked?
+        DWORD dwValue, dwSize;
+        if (pEntry->bChecked)
+        {
+            dwValue = pEntry->dwCheckedValue;
+        }
+        else
+        {
+            if (pEntry->bHasUncheckedValue)
+            {
+                dwValue = pEntry->dwUncheckedValue;
+            }
+            else
+            {
+                // there is no unchecked value
+                RegCloseKey(hkeyTarget);
+                continue;   // ignore
+            }
+        }
+
+        // set the value
+        dwSize = sizeof(dwValue);
+        RegSetValueExW(hkeyTarget, pEntry->szValueName, 0, REG_DWORD,
+                       LPBYTE(&dwValue), dwSize);
+
+        // close now
+        RegCloseKey(hkeyTarget);
+    }
+
+    // scan advanced settings for user's settings
+    DWORD dwMask = 0;
+    SHELLSTATE ShellState;
+    ZeroMemory(&ShellState, sizeof(ShellState));
+    ScanAdvancedSettings(&ShellState, &dwMask);
+
+    // update user's settings
+    SHGetSetSettings(&ShellState, dwMask, TRUE);
+
+    // notify all
+    SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, 0);
+    
+    EnumWindows(RefreshBrowsersCallback, NULL);
+}
+
+INT_PTR CALLBACK
 FolderOptionsViewDlg(
-    HWND hwndDlg,
-    UINT uMsg,
-    WPARAM wParam,
-    LPARAM lParam
-)
+    HWND    hwndDlg,
+    UINT    uMsg,
+    WPARAM  wParam,
+    LPARAM  lParam)
 {
+    INT_PTR Result;
+    NMTVCUSTOMDRAW *Draw;
+
     switch(uMsg)
     {
         case WM_INITDIALOG:
-            InitializeFolderOptionsListCtrl(hwndDlg);
-            return TRUE;
+            return ViewDlg_OnInitDialog(hwndDlg);
+        case WM_COMMAND:
+            switch (LOWORD(wParam))
+            {
+                case 14004: // Restore Defaults
+                    Advanced_RestoreDefaults(hwndDlg);
+                    break;
+            }
+            break;
+        case WM_NOTIFY:
+            switch (LPNMHDR(lParam)->code)
+            {
+                case NM_CLICK:  // clicked on treeview
+                    ViewDlg_OnTreeViewClick(hwndDlg);
+                    break;
+                case NM_CUSTOMDRAW:     // custom draw (for graying)
+                    Draw = (NMTVCUSTOMDRAW *)lParam;
+                    Result = ViewDlg_OnTreeCustomDraw(hwndDlg, Draw);
+                    SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, Result);
+                    return Result;
+                case TVN_KEYDOWN:       // key is down
+                    ViewDlg_OnTreeViewKeyDown(hwndDlg, (TV_KEYDOWN *)lParam);
+                    break;
+                case PSN_APPLY:         // [Apply] is clicked
+                    ViewDlg_Apply(hwndDlg);
+                    break;
+                default:
+                    break;
+            }
+            break;
     }
 
     return FALSE;
-
 }
 
 static
@@ -179,7 +1322,8 @@ InitializeFileTypesListCtrlColumns(HWND hDlgCtrl)
     if (!LoadStringW(shell32_hInstance, IDS_FILE_TYPES, szName, sizeof(szName) / sizeof(WCHAR)))
     {
         /* default to english */
-        wcscpy(szName, L"FileTypes");
+        wcscpy(szName, L"File Types");
+        ERR("Failed to load localized string!\n");
     }
 
     col.iSubItem   = 1;
@@ -213,6 +1357,7 @@ InsertFileType(HWND hDlgCtrl, WCHAR * szName, PINT iItem, WCHAR * szFile)
     HKEY hKey;
     LVITEMW lvItem;
     DWORD dwSize;
+    DWORD dwType;
 
     if (szName[0] != L'.')
     {
@@ -266,19 +1411,34 @@ InsertFileType(HWND hDlgCtrl, WCHAR * szName, PINT iItem, WCHAR * szFile)
         RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)Entry->FileDescription, &dwSize);
     }
 
+    /* Read the EditFlags value */
+    Entry->EditFlags = 0;
+    if (!RegQueryValueExW(hKey, L"EditFlags", NULL, &dwType, NULL, &dwSize))
+    {
+        if ((dwType == REG_DWORD || dwType == REG_BINARY) && dwSize == sizeof(DWORD))
+            RegQueryValueExW(hKey, L"EditFlags", NULL, NULL, (LPBYTE)&Entry->EditFlags, &dwSize);
+    }
+
     /* close key */
     RegCloseKey(hKey);
 
+    /* Do not add excluded entries */
+    if (Entry->EditFlags & 0x00000001) //FTA_Exclude
+    {
+        HeapFree(GetProcessHeap(), 0, Entry);
+        return;
+    }
+
     /* convert extension to upper case */
     wcscpy(Entry->FileExtension, szName);
     _wcsupr(Entry->FileExtension);
 
     if (!Entry->FileDescription[0])
     {
-        /* construct default 'FileExtensionFile' */
-        wcscpy(Entry->FileDescription, &Entry->FileExtension[1]);
-        wcscat(Entry->FileDescription, L" ");
-        wcscat(Entry->FileDescription, szFile);
+        /* construct default 'FileExtensionFile' by formatting the uppercase extension
+           with IDS_FILE_EXT_TYPE, outputting something like a l18n 'INI File' */
+
+        StringCchPrintf(Entry->FileDescription, _countof(Entry->FileDescription), szFile, &Entry->FileExtension[1]);
     }
 
     ZeroMemory(&lvItem, sizeof(LVITEMW));
@@ -294,8 +1454,8 @@ InsertFileType(HWND hDlgCtrl, WCHAR * szName, PINT iItem, WCHAR * szFile)
     lvItem.pszText = Entry->FileDescription;
     lvItem.iItem = *iItem;
     lvItem.iSubItem = 1;
+    ListView_SetItem(hDlgCtrl, &lvItem);
 
-    (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&lvItem);
     (*iItem)++;
 }
 
@@ -305,15 +1465,20 @@ CALLBACK
 ListViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
 {
     PFOLDER_FILE_TYPE_ENTRY Entry1, Entry2;
+    int x;
 
     Entry1 = (PFOLDER_FILE_TYPE_ENTRY)lParam1;
     Entry2 = (PFOLDER_FILE_TYPE_ENTRY)lParam2;
 
-    return wcsicmp(Entry1->FileExtension, Entry2->FileExtension);
+    x = wcsicmp(Entry1->FileExtension, Entry2->FileExtension);
+    if (x != 0)
+        return x;
+
+    return wcsicmp(Entry1->FileDescription, Entry2->FileDescription);
 }
 
 static
-BOOL
+PFOLDER_FILE_TYPE_ENTRY
 InitializeFileTypesListCtrl(HWND hwndDlg)
 {
     HWND hDlgCtrl;
@@ -328,33 +1493,40 @@ InitializeFileTypesListCtrl(HWND hwndDlg)
     InitializeFileTypesListCtrlColumns(hDlgCtrl);
 
     szFile[0] = 0;
-    if (!LoadStringW(shell32_hInstance, IDS_SHV_COLUMN1, szFile, sizeof(szFile) / sizeof(WCHAR)))
+    if (!LoadStringW(shell32_hInstance, IDS_FILE_EXT_TYPE, szFile, _countof(szFile)))
     {
         /* default to english */
-        wcscpy(szFile, L"File");
+        wcscpy(szFile, L"%s File");
     }
-    szFile[(sizeof(szFile)/sizeof(WCHAR))-1] = 0;
+    szFile[(_countof(szFile)) - 1] = 0;
 
-    dwName = sizeof(szName) / sizeof(WCHAR);
+    dwName = _countof(szName);
 
-    while(RegEnumKeyExW(HKEY_CLASSES_ROOT, dwIndex++, szName, &dwName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+    while (RegEnumKeyExW(HKEY_CLASSES_ROOT, dwIndex++, szName, &dwName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
     {
         InsertFileType(hDlgCtrl, szName, &iItem, szFile);
-        dwName = sizeof(szName) / sizeof(WCHAR);
+        dwName = _countof(szName);
     }
 
+    /* Leave if the list is empty */
+    if (iItem == 0)
+        return NULL;
+
     /* sort list */
     ListView_SortItems(hDlgCtrl, ListViewCompareProc, NULL);
 
     /* select first item */
     ZeroMemory(&lvItem, sizeof(LVITEMW));
     lvItem.mask = LVIF_STATE;
-    lvItem.stateMask = (UINT) - 1;
+    lvItem.stateMask = (UINT)-1;
     lvItem.state = LVIS_FOCUSED | LVIS_SELECTED;
     lvItem.iItem = 0;
-    (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&lvItem);
+    ListView_SetItem(hDlgCtrl, &lvItem);
 
-    return TRUE;
+    lvItem.mask = LVIF_PARAM;
+    ListView_GetItem(hDlgCtrl, &lvItem);
+
+    return (PFOLDER_FILE_TYPE_ENTRY)lvItem.lParam;
 }
 
 static
@@ -384,15 +1556,13 @@ FindSelectedItem(
     return NULL;
 }
 
-static
 INT_PTR
 CALLBACK
 FolderOptionsFileTypesDlg(
     HWND hwndDlg,
     UINT uMsg,
     WPARAM wParam,
-    LPARAM lParam
-)
+    LPARAM lParam)
 {
     LPNMLISTVIEW lppl;
     LVITEMW lvItem;
@@ -403,8 +1573,14 @@ FolderOptionsFileTypesDlg(
     switch(uMsg)
     {
         case WM_INITDIALOG:
-            InitializeFileTypesListCtrl(hwndDlg);
+            pItem = InitializeFileTypesListCtrl(hwndDlg);
+
+            /* Disable the Delete button if the listview is empty or
+               the selected item should not be deleted by the user */
+            if (pItem == NULL || (pItem->EditFlags & 0x00000010)) // FTA_NoRemove
+                EnableWindow(GetDlgItem(hwndDlg, 14002), FALSE);
             return TRUE;
+
         case WM_COMMAND:
             switch(LOWORD(wParam))
             {
@@ -418,8 +1594,8 @@ FolderOptionsFileTypesDlg(
                     }
                     break;
             }
-
             break;
+
         case WM_NOTIFY:
             lppl = (LPNMLISTVIEW) lParam;
 
@@ -458,8 +1634,19 @@ FolderOptionsFileTypesDlg(
                     swprintf(Buffer, FormatBuffer, &pItem->FileExtension[1], &pItem->FileDescription[0], &pItem->FileDescription[0]);
                     /* update dialog */
                     SetDlgItemTextW(hwndDlg, 14007, Buffer);
+
+                    /* Enable the Delete button */
+                    if (pItem->EditFlags & 0x00000010) // FTA_NoRemove
+                        EnableWindow(GetDlgItem(hwndDlg, 14002), FALSE);
+                    else
+                        EnableWindow(GetDlgItem(hwndDlg, 14002), TRUE);
                 }
             }
+            else if (lppl->hdr.code == PSN_SETACTIVE)
+            {
+                /* On page activation, set the focus to the listview */
+                SetFocus(GetDlgItem(hwndDlg, 14000));
+            }
             break;
     }