/*
- * Open With Context Menu extension
+ * Folder Options
*
* Copyright 2007 Johannes Anderwald <johannes.anderwald@reactos.org>
* Copyright 2016-2018 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
WINE_DEFAULT_DEBUG_CHANNEL (fprop);
-/// Folder Options:
-/// CLASSKEY = HKEY_CLASSES_ROOT\CLSID\{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}
-/// DefaultIcon = %SystemRoot%\system32\SHELL32.dll,-210
-/// Verbs: Open / RunAs
-/// Cmd: rundll32.exe shell32.dll,Options_RunDLL 0
+// Folder Options:
+// CLASSKEY = HKEY_CLASSES_ROOT\CLSID\{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}
-/// ShellFolder Attributes: 0x0
+/////////////////////////////////////////////////////////////////////////////
+// strings
-typedef struct
-{
- WCHAR FileExtension[30];
- WCHAR FileDescription[100];
- WCHAR ClassKey[MAX_PATH];
- DWORD EditFlags;
- WCHAR AppName[64];
- HICON hIconLarge;
- HICON hIconSmall;
- WCHAR ProgramPath[MAX_PATH];
-} FOLDER_FILE_TYPE_ENTRY, *PFOLDER_FILE_TYPE_ENTRY;
-
-// uniquely-defined icon entry for Advanced Settings
-typedef struct ADVANCED_ICON
-{
- 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
+// path to shell32
+LPCWSTR g_pszShell32 = L"%SystemRoot%\\system32\\shell32.dll";
- // extract a small icon
- HICON hIconSmall = NULL;
- ExtractIconExW(pszPath, nIconIndex, NULL, &hIconSmall, 1);
- if (hIconSmall == NULL)
- return -1; // failure
+// the space characters
+LPCWSTR g_pszSpace = L" \t\n\r\f\v";
- // 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;
+/////////////////////////////////////////////////////////////////////////////
+// utility functions
- // 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)
+HBITMAP Create24BppBitmap(HDC hDC, INT cx, INT cy)
{
BITMAPINFO bi;
LPVOID pvBits;
return hbm;
}
-static HBITMAP BitmapFromIcon(HICON hIcon, INT cx, INT cy)
+HBITMAP BitmapFromIcon(HICON hIcon, INT cx, INT cy)
{
HDC hDC = CreateCompatibleDC(NULL);
if (!hDC)
return hbm;
}
-static HBITMAP
-CreateCheckImage(HDC hDC, BOOL bCheck, BOOL bEnabled = TRUE)
+HBITMAP CreateCheckImage(HDC hDC, BOOL bCheck, BOOL bEnabled)
{
INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
return hbm; // success
}
-static HBITMAP
-CreateCheckMask(HDC hDC)
+HBITMAP CreateCheckMask(HDC hDC)
{
INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
return hbm; // success
}
-static HBITMAP
-CreateRadioImage(HDC hDC, BOOL bCheck, BOOL bEnabled = TRUE)
+HBITMAP CreateRadioImage(HDC hDC, BOOL bCheck, BOOL bEnabled)
{
INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
return hbm; // success
}
-static HBITMAP
-CreateRadioMask(HDC hDC)
+HBITMAP CreateRadioMask(HDC hDC)
{
INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
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)
+// CMSGlobalFolderOptionsStub --- The owner window of Folder Options.
+// This window hides taskbar button of Folder Options.
+class CMSGlobalFolderOptionsStub : public CWindowImpl<CMSGlobalFolderOptionsStub>
{
- 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));
+public:
+ DECLARE_WND_CLASS_EX(_T("MSGlobalFolderOptionsStub"), 0, COLOR_WINDOWTEXT)
- // 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);
+ BEGIN_MSG_MAP(CMSGlobalFolderOptionsStub)
+ END_MSG_MAP()
+};
- ++dwIndex;
- }
+/////////////////////////////////////////////////////////////////////////////
- return TRUE; // success
-}
+EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
-static BOOL
-Advanced_LoadAll(VOID)
+static int CALLBACK
+PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
{
- 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)
+ // NOTE: This callback is needed to set large icon correctly.
+ HICON hIcon;
+ switch (uMsg)
{
- HKEY hkeyChild;
- if (RegOpenKeyExW(hKey, szKeyName, 0, KEY_READ,
- &hkeyChild) != ERROR_SUCCESS)
+ case PSCB_INITIALIZED:
{
- ++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)
+ hIcon = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPTIONS));
+ SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
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);
+ return 0;
}
-EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
-
static VOID
-UpdateGeneralIcons(HWND hDlg)
+ShowFolderOptionsDialog(HWND hWnd, HINSTANCE hInst)
{
- 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);
+ PROPSHEETHEADERW pinfo;
+ HPROPSHEETPAGE hppages[3];
+ HPROPSHEETPAGE hpage;
+ UINT num_pages = 0;
+ WCHAR szOptions[100];
- 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);
- }
- }
- }
+ hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL, FolderOptionsGeneralDlg, 0, NULL);
+ if (hpage)
+ hppages[num_pages++] = hpage;
- // 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);
+ hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW, FolderOptionsViewDlg, 0, NULL);
+ if (hpage)
+ hppages[num_pages++] = hpage;
- 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);
- }
- }
- }
+ hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES, FolderOptionsFileTypesDlg, 0, NULL);
+ if (hpage)
+ hppages[num_pages++] = hpage;
- // Clean up
- if(hTaskIcon)
- DeleteObject(hTaskIcon);
- if(hFolderIcon)
- DeleteObject(hFolderIcon);
- if(hClickIcon)
- DeleteObject(hClickIcon);
-
- return;
-}
+ szOptions[0] = 0;
+ LoadStringW(shell32_hInstance, IDS_FOLDER_OPTIONS, szOptions, _countof(szOptions));
+ szOptions[_countof(szOptions) - 1] = 0;
-INT_PTR
-CALLBACK
-FolderOptionsGeneralDlg(
- HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam
-)
-{
- switch(uMsg)
+ // the stub window to hide taskbar button
+ DWORD style = WS_DISABLED | WS_CLIPSIBLINGS | WS_CAPTION;
+ DWORD exstyle = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW;
+ CMSGlobalFolderOptionsStub stub;
+ if (!stub.Create(NULL, NULL, NULL, style, exstyle))
{
- 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;
+ ERR("stub.Create failed\n");
+ return;
}
- return FALSE;
-}
-
-static BOOL
-ViewDlg_OnInitDialog(HWND hwndDlg)
-{
- HWND hwndTreeView = GetDlgItem(hwndDlg, 14003);
-
- s_hImageList = CreateTreeImageList();
- TreeView_SetImageList(hwndTreeView, s_hImageList, TVSIL_NORMAL);
-
- Advanced_LoadAll();
- Advanced_SortAll();
- Advanced_InsertAll(hwndTreeView);
-
- 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;
+ memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW));
+ pinfo.dwSize = sizeof(PROPSHEETHEADERW);
+ pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_USEICONID | PSH_USECALLBACK;
+ pinfo.hwndParent = stub;
+ pinfo.nPages = num_pages;
+ pinfo.phpage = hppages;
+ pinfo.pszIcon = MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPTIONS);
+ pinfo.pszCaption = szOptions;
+ pinfo.pfnCallback = PropSheetProc;
- 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);
+ PropertySheetW(&pinfo);
- // redraw the item
- RECT rcItem;
- TreeView_GetItemRect(hwndTreeView, hItem, &rcItem, FALSE);
- InvalidateRect(hwndTreeView, &rcItem, TRUE);
- return TRUE; // success
+ stub.DestroyWindow();
}
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 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)
+Options_RunDLLCommon(HWND hWnd, HINSTANCE hInst, int fOptions, DWORD nCmdShow)
{
- NMCUSTOMDRAW& nmcd = Draw->nmcd;
- switch (nmcd.dwDrawStage)
+ switch(fOptions)
{
- 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;
- }
- }
+ case 0:
+ ShowFolderOptionsDialog(hWnd, hInst);
break;
- default:
+ case 1:
+ // show taskbar options dialog
+ FIXME("notify explorer to show taskbar options dialog");
+ //PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0);
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)
-{
- INT_PTR Result;
- NMTVCUSTOMDRAW *Draw;
-
- switch(uMsg)
- {
- case WM_INITDIALOG:
- 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
-VOID
-InitializeFileTypesListCtrlColumns(HWND hDlgCtrl)
-{
- RECT clientRect;
- LVCOLUMNW col;
- WCHAR szName[50];
- DWORD dwStyle;
- int columnSize = 140;
-
-
- if (!LoadStringW(shell32_hInstance, IDS_COLUMN_EXTENSION, szName, sizeof(szName) / sizeof(WCHAR)))
- {
- /* default to english */
- wcscpy(szName, L"Extensions");
- }
-
- /* make sure its null terminated */
- szName[(sizeof(szName)/sizeof(WCHAR))-1] = 0;
-
- GetClientRect(hDlgCtrl, &clientRect);
- ZeroMemory(&col, sizeof(LV_COLUMN));
- columnSize = 140; //FIXME
- col.iSubItem = 0;
- col.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
- col.fmt = LVCFMT_FIXED_WIDTH;
- col.cx = columnSize | LVCFMT_LEFT;
- col.cchTextMax = wcslen(szName);
- col.pszText = szName;
- (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM)&col);
-
- if (!LoadStringW(shell32_hInstance, IDS_FILE_TYPES, szName, sizeof(szName) / sizeof(WCHAR)))
- {
- /* default to english */
- wcscpy(szName, L"File Types");
- ERR("Failed to load localized string!\n");
- }
-
- col.iSubItem = 1;
- col.cx = clientRect.right - clientRect.left - columnSize;
- col.cchTextMax = wcslen(szName);
- col.pszText = szName;
- (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM)&col);
-
- /* set full select style */
- dwStyle = (DWORD) SendMessage(hDlgCtrl, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
- dwStyle = dwStyle | LVS_EX_FULLROWSELECT;
- SendMessage(hDlgCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
-}
-
-static BOOL
-DeleteExt(HWND hwndDlg, LPCWSTR pszExt)
-{
- if (*pszExt != L'.')
- return FALSE;
-
- // open ".ext" key
- HKEY hKey;
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, pszExt, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
- return FALSE;
-
- // query "extfile" key name
- WCHAR szValue[64] = { 0 };
- DWORD cbValue = sizeof(szValue);
- RegQueryValueExW(hKey, NULL, NULL, NULL, LPBYTE(szValue), &cbValue);
- RegCloseKey(hKey);
-
- // delete "extfile" key (if any)
- if (szValue[0])
- SHDeleteKeyW(HKEY_CLASSES_ROOT, szValue);
-
- // delete ".ext" key
- return SHDeleteKeyW(HKEY_CLASSES_ROOT, pszExt) == ERROR_SUCCESS;
-}
-
-static inline HICON
-DoExtractIcon(PFOLDER_FILE_TYPE_ENTRY Entry, LPCWSTR IconPath,
- INT iIndex = 0, BOOL bSmall = FALSE)
-{
- HICON hIcon = NULL;
-
- if (iIndex < 0)
- {
- // A negative value will be interpreted as a negated resource ID.
- iIndex = -iIndex;
-
- INT cx, cy;
- HINSTANCE hDLL = LoadLibraryExW(IconPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
- if (bSmall)
- {
- cx = GetSystemMetrics(SM_CXSMICON);
- cy = GetSystemMetrics(SM_CYSMICON);
- }
- else
- {
- cx = GetSystemMetrics(SM_CXICON);
- cy = GetSystemMetrics(SM_CYICON);
- }
- hIcon = HICON(LoadImageW(hDLL, MAKEINTRESOURCEW(iIndex), IMAGE_ICON,
- cx, cy, 0));
- FreeLibrary(hDLL);
- }
- else
- {
- // A positive value is icon index.
- if (bSmall)
- ExtractIconExW(IconPath, iIndex, NULL, &hIcon, 1);
- else
- ExtractIconExW(IconPath, iIndex, &hIcon, NULL, 1);
- }
- return hIcon;
-}
-
-static void
-DoFileTypeIconLocation(PFOLDER_FILE_TYPE_ENTRY Entry, LPCWSTR IconLocation)
-{
- // Expand the REG_EXPAND_SZ string by environment variables
- WCHAR szLocation[MAX_PATH + 32];
- if (!ExpandEnvironmentStringsW(IconLocation, szLocation, _countof(szLocation)))
- {
- return;
- }
-
- INT nIndex = PathParseIconLocationW(szLocation);
- Entry->hIconLarge = DoExtractIcon(Entry, szLocation, nIndex, FALSE);
- Entry->hIconSmall = DoExtractIcon(Entry, szLocation, nIndex, TRUE);
-}
-
-static BOOL
-GetFileTypeIconsEx(PFOLDER_FILE_TYPE_ENTRY Entry, LPCWSTR IconLocation)
-{
- Entry->hIconLarge = Entry->hIconSmall = NULL;
-
- if (lstrcmpiW(Entry->FileExtension, L".exe") == 0 ||
- lstrcmpiW(Entry->FileExtension, L".scr") == 0)
- {
- // It's an executable
- Entry->hIconLarge = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_EXE));
- Entry->hIconSmall = HICON(LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_EXE), IMAGE_ICON,
- GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0));
- }
- else if (lstrcmpW(IconLocation, L"%1") == 0)
- {
- return FALSE; // self icon
- }
- else
- {
- DoFileTypeIconLocation(Entry, IconLocation);
- }
-
- return Entry->hIconLarge && Entry->hIconSmall;
-}
-
-static BOOL
-GetFileTypeIconsByKey(HKEY hKey, PFOLDER_FILE_TYPE_ENTRY Entry)
-{
- Entry->hIconLarge = Entry->hIconSmall = NULL;
-
- // Open the "DefaultIcon" registry key
- HKEY hDefIconKey;
- LONG nResult = RegOpenKeyExW(hKey, L"DefaultIcon", 0, KEY_READ, &hDefIconKey);
- if (nResult != ERROR_SUCCESS)
- return FALSE;
-
- // Get the icon location
- WCHAR szLocation[MAX_PATH + 32] = { 0 };
- DWORD dwSize = sizeof(szLocation);
- nResult = RegQueryValueExW(hDefIconKey, NULL, NULL, NULL, LPBYTE(szLocation), &dwSize);
-
- RegCloseKey(hDefIconKey);
-
- if (nResult != ERROR_SUCCESS || szLocation[0] == 0)
- return FALSE;
-
- return GetFileTypeIconsEx(Entry, szLocation);
-}
-
-static BOOL
-QueryFileDescription(LPCWSTR ProgramPath, LPWSTR pszName, INT cchName)
-{
- SHFILEINFOW FileInfo = { 0 };
- if (SHGetFileInfoW(ProgramPath, 0, &FileInfo, sizeof(FileInfo), SHGFI_DISPLAYNAME))
- {
- StringCchCopyW(pszName, cchName, FileInfo.szDisplayName);
- return TRUE;
- }
-
- return !!GetFileTitleW(ProgramPath, pszName, cchName);
-}
-
-static BOOL
-InsertFileType(HWND hListView, LPCWSTR szName, INT iItem, LPCWSTR szFile)
-{
- PFOLDER_FILE_TYPE_ENTRY Entry;
- HKEY hKey;
- LVITEMW lvItem;
- DWORD dwSize;
- DWORD dwType;
-
- if (szName[0] != L'.')
- {
- /* FIXME handle URL protocol handlers */
- return FALSE;
- }
-
- // get imagelists of listview
- HIMAGELIST himlLarge = ListView_GetImageList(hListView, LVSIL_NORMAL);
- HIMAGELIST himlSmall = ListView_GetImageList(hListView, LVSIL_SMALL);
-
- /* allocate file type entry */
- Entry = (PFOLDER_FILE_TYPE_ENTRY)HeapAlloc(GetProcessHeap(), 0, sizeof(FOLDER_FILE_TYPE_ENTRY));
- if (!Entry)
- return FALSE;
-
- /* open key */
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szName, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
- {
- HeapFree(GetProcessHeap(), 0, Entry);
- return FALSE;
- }
-
- /* FIXME check for duplicates */
-
- /* query for the default key */
- dwSize = sizeof(Entry->ClassKey);
- if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)Entry->ClassKey, &dwSize) != ERROR_SUCCESS)
- {
- /* no link available */
- Entry->ClassKey[0] = 0;
- }
-
- if (Entry->ClassKey[0])
- {
- HKEY hTemp;
- /* try open linked key */
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, Entry->ClassKey, 0, KEY_READ, &hTemp) == ERROR_SUCCESS)
- {
- /* use linked key */
- RegCloseKey(hKey);
- hKey = hTemp;
- }
- }
-
- /* read friendly type name */
- if (RegLoadMUIStringW(hKey, L"FriendlyTypeName", Entry->FileDescription, sizeof(Entry->FileDescription), NULL, 0, NULL) != ERROR_SUCCESS)
- {
- /* read file description */
- dwSize = sizeof(Entry->FileDescription);
- Entry->FileDescription[0] = 0;
-
- /* read default key */
- 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);
- }
-
- /* convert extension to upper case */
- wcscpy(Entry->FileExtension, szName);
- _wcsupr(Entry->FileExtension);
-
- /* get icon */
- if (!GetFileTypeIconsByKey(hKey, Entry))
- {
- // set default icon
- Entry->hIconLarge = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPTIONS));
- INT cxSmall = GetSystemMetrics(SM_CXSMICON);
- INT cySmall = GetSystemMetrics(SM_CYSMICON);
- Entry->hIconSmall = HICON(LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPTIONS),
- IMAGE_ICON, cxSmall, cySmall, 0));
- }
-
- /* close key */
- RegCloseKey(hKey);
-
- // get program path and app name
- DWORD cch = _countof(Entry->ProgramPath);
- if (S_OK == AssocQueryStringW(ASSOCF_INIT_IGNOREUNKNOWN, ASSOCSTR_EXECUTABLE,
- Entry->FileExtension, NULL, Entry->ProgramPath, &cch))
- {
- QueryFileDescription(Entry->ProgramPath, Entry->AppName, _countof(Entry->AppName));
- }
- else
- {
- Entry->ProgramPath[0] = Entry->AppName[0] = 0;
- }
-
- // add icon to imagelist
- INT iLargeImage = -1, iSmallImage = -1;
- if (Entry->hIconLarge && Entry->hIconSmall)
- {
- iLargeImage = ImageList_AddIcon(himlLarge, Entry->hIconLarge);
- iSmallImage = ImageList_AddIcon(himlSmall, Entry->hIconSmall);
- ASSERT(iLargeImage == iSmallImage);
- }
-
- /* Do not add excluded entries */
- if (Entry->EditFlags & 0x00000001) //FTA_Exclude
- {
- DestroyIcon(Entry->hIconLarge);
- DestroyIcon(Entry->hIconSmall);
- HeapFree(GetProcessHeap(), 0, Entry);
- return FALSE;
- }
-
- if (!Entry->FileDescription[0])
- {
- /* 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));
- lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
- lvItem.iSubItem = 0;
- lvItem.pszText = &Entry->FileExtension[1];
- lvItem.iItem = iItem;
- lvItem.lParam = (LPARAM)Entry;
- lvItem.iImage = iSmallImage;
- SendMessageW(hListView, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
-
- ZeroMemory(&lvItem, sizeof(LVITEMW));
- lvItem.mask = LVIF_TEXT;
- lvItem.pszText = Entry->FileDescription;
- lvItem.iItem = iItem;
- lvItem.iSubItem = 1;
- ListView_SetItem(hListView, &lvItem);
-
- return TRUE;
-}
-
-static
-int
-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;
-
- x = wcsicmp(Entry1->FileExtension, Entry2->FileExtension);
- if (x != 0)
- return x;
-
- return wcsicmp(Entry1->FileDescription, Entry2->FileDescription);
-}
-
-static
-PFOLDER_FILE_TYPE_ENTRY
-InitializeFileTypesListCtrl(HWND hwndDlg)
-{
- HWND hDlgCtrl;
- DWORD dwIndex = 0;
- WCHAR szName[50];
- WCHAR szFile[100];
- DWORD dwName;
- LVITEMW lvItem;
- INT iItem = 0;
- HIMAGELIST himlLarge, himlSmall;
-
- // create imagelists
- himlLarge = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
- ILC_COLOR32 | ILC_MASK, 256, 20);
- himlSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
- ILC_COLOR32 | ILC_MASK, 256, 20);
-
- // set imagelists to listview.
- hDlgCtrl = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
- ListView_SetImageList(hDlgCtrl, himlLarge, LVSIL_NORMAL);
- ListView_SetImageList(hDlgCtrl, himlSmall, LVSIL_SMALL);
- InitializeFileTypesListCtrlColumns(hDlgCtrl);
-
- szFile[0] = 0;
- if (!LoadStringW(shell32_hInstance, IDS_FILE_EXT_TYPE, szFile, _countof(szFile)))
- {
- /* default to english */
- wcscpy(szFile, L"%s File");
- }
- szFile[(_countof(szFile)) - 1] = 0;
-
- dwName = _countof(szName);
-
- while (RegEnumKeyExW(HKEY_CLASSES_ROOT, dwIndex++, szName, &dwName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
- {
- if (InsertFileType(hDlgCtrl, szName, iItem, szFile))
- ++iItem;
- 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.state = LVIS_FOCUSED | LVIS_SELECTED;
- lvItem.iItem = 0;
- ListView_SetItem(hDlgCtrl, &lvItem);
-
- lvItem.mask = LVIF_PARAM;
- ListView_GetItem(hDlgCtrl, &lvItem);
-
- return (PFOLDER_FILE_TYPE_ENTRY)lvItem.lParam;
-}
-
-static inline
-PFOLDER_FILE_TYPE_ENTRY
-GetListViewEntry(HWND hListView, INT iItem = -1)
-{
- if (iItem == -1)
- {
- iItem = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
- if (iItem == -1)
- return NULL;
- }
-
- LV_ITEMW lvItem = { LVIF_PARAM, iItem };
- if (ListView_GetItem(hListView, &lvItem))
- return (PFOLDER_FILE_TYPE_ENTRY)lvItem.lParam;
-
- return NULL;
-}
-
-struct NEWEXT_DIALOG
-{
- HWND hwndDlg;
- HWND hwndLV;
- RECT rcDlg;
- BOOL bAdvanced;
- INT dy;
- WCHAR szExt[16];
- WCHAR szFileType[64];
-};
-
-static VOID
-NewExtDlg_OnAdvanced(HWND hwndDlg, NEWEXT_DIALOG *pNewExt)
-{
- // If "Advanced" button was clicked, then we shrink or expand the dialog.
- WCHAR szText[64];
- RECT rc, rc1, rc2;
-
- GetWindowRect(hwndDlg, &rc);
- rc.bottom = rc.top + (pNewExt->rcDlg.bottom - pNewExt->rcDlg.top);
-
- GetWindowRect(GetDlgItem(hwndDlg, IDOK), &rc1);
- MapWindowPoints(NULL, hwndDlg, (POINT *)&rc1, 2);
-
- GetWindowRect(GetDlgItem(hwndDlg, IDCANCEL), &rc2);
- MapWindowPoints(NULL, hwndDlg, (POINT *)&rc2, 2);
-
- if (pNewExt->bAdvanced)
- {
- rc1.top += pNewExt->dy;
- rc1.bottom += pNewExt->dy;
-
- rc2.top += pNewExt->dy;
- rc2.bottom += pNewExt->dy;
-
- ShowWindow(GetDlgItem(hwndDlg, IDC_NEWEXT_ASSOC), SW_SHOWNOACTIVATE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_NEWEXT_COMBOBOX), SW_SHOWNOACTIVATE);
-
- LoadStringW(shell32_hInstance, IDS_NEWEXT_ADVANCED_LEFT, szText, _countof(szText));
- SetDlgItemTextW(hwndDlg, IDC_NEWEXT_ADVANCED, szText);
-
- SetFocus(GetDlgItem(hwndDlg, IDC_NEWEXT_COMBOBOX));
- }
- else
- {
- rc1.top -= pNewExt->dy;
- rc1.bottom -= pNewExt->dy;
-
- rc2.top -= pNewExt->dy;
- rc2.bottom -= pNewExt->dy;
-
- ShowWindow(GetDlgItem(hwndDlg, IDC_NEWEXT_ASSOC), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_NEWEXT_COMBOBOX), SW_HIDE);
-
- LoadStringW(shell32_hInstance, IDS_NEWEXT_ADVANCED_RIGHT, szText, _countof(szText));
- SetDlgItemTextW(hwndDlg, IDC_NEWEXT_ADVANCED, szText);
-
- rc.bottom -= pNewExt->dy;
-
- LoadStringW(shell32_hInstance, IDS_NEWEXT_NEW, szText, _countof(szText));
- SetDlgItemTextW(hwndDlg, IDC_NEWEXT_COMBOBOX, szText);
- }
-
- HDWP hDWP = BeginDeferWindowPos(3);
-
- if (hDWP)
- hDWP = DeferWindowPos(hDWP, GetDlgItem(hwndDlg, IDOK), NULL,
- rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
- SWP_NOACTIVATE | SWP_NOZORDER);
- if (hDWP)
- hDWP = DeferWindowPos(hDWP, GetDlgItem(hwndDlg, IDCANCEL), NULL,
- rc2.left, rc2.top, rc2.right - rc2.left, rc2.bottom - rc2.top,
- SWP_NOACTIVATE | SWP_NOZORDER);
- if (hDWP)
- hDWP = DeferWindowPos(hDWP, hwndDlg, NULL,
- rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
- SWP_NOACTIVATE | SWP_NOZORDER);
-
- if (hDWP)
- EndDeferWindowPos(hDWP);
-}
-
-static BOOL
-NewExtDlg_OnInitDialog(HWND hwndDlg, NEWEXT_DIALOG *pNewExt)
-{
- WCHAR szText[64];
-
- pNewExt->hwndDlg = hwndDlg;
- pNewExt->bAdvanced = FALSE;
-
- GetWindowRect(hwndDlg, &pNewExt->rcDlg);
-
- RECT rc1, rc2;
- GetWindowRect(GetDlgItem(hwndDlg, IDC_NEWEXT_EDIT), &rc1);
- GetWindowRect(GetDlgItem(hwndDlg, IDC_NEWEXT_COMBOBOX), &rc2);
- pNewExt->dy = rc2.top - rc1.top;
-
- LoadStringW(shell32_hInstance, IDS_NEWEXT_NEW, szText, _countof(szText));
- SendDlgItemMessageW(hwndDlg, IDC_NEWEXT_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)szText);
- SendDlgItemMessageW(hwndDlg, IDC_NEWEXT_COMBOBOX, CB_SETCURSEL, 0, 0);
-
- SendDlgItemMessageW(hwndDlg, IDC_NEWEXT_EDIT, EM_SETLIMITTEXT, _countof(pNewExt->szExt) - 1, 0);
-
- NewExtDlg_OnAdvanced(hwndDlg, pNewExt);
-
- return TRUE;
-}
-
-static void
-StringTrimW(LPWSTR pszText)
-{
- LPWSTR pch = pszText;
- while (iswspace(*pch))
- pch++;
-
- LPWSTR pchFirst, pchLast;
- pchFirst = pchLast = pch;
- while (*pch && !iswspace(*pch))
- {
- ++pch;
- pchLast = pch;
- }
-
- INT_PTR cch = pchLast - pchFirst;
- MoveMemory(pszText, pchFirst, cch * sizeof(WCHAR));
- pszText[cch] = 0;
-}
-
-static BOOL
-NewExtDlg_OnOK(HWND hwndDlg, NEWEXT_DIALOG *pNewExt)
-{
- LV_FINDINFO find;
- INT iItem;
-
- GetDlgItemTextW(hwndDlg, IDC_NEWEXT_EDIT, pNewExt->szExt, _countof(pNewExt->szExt));
- StringTrimW(pNewExt->szExt);
- CharUpperW(pNewExt->szExt);
-
- GetDlgItemTextW(hwndDlg, IDC_NEWEXT_COMBOBOX, pNewExt->szFileType, _countof(pNewExt->szFileType));
- StringTrimW(pNewExt->szFileType);
-
- if (pNewExt->szExt[0] == 0)
- {
- WCHAR szText[128], szTitle[128];
- LoadStringW(shell32_hInstance, IDS_NEWEXT_SPECIFY_EXT, szText, _countof(szText));
- szText[_countof(szText) - 1] = 0;
- LoadStringW(shell32_hInstance, IDS_FILE_TYPES, szTitle, _countof(szTitle));
- szTitle[_countof(szTitle) - 1] = 0;
- MessageBoxW(hwndDlg, szText, szTitle, MB_ICONERROR);
- return FALSE;
- }
-
- ZeroMemory(&find, sizeof(find));
- find.flags = LVFI_STRING;
- if (pNewExt->szExt[0] == L'.')
- {
- find.psz = &pNewExt->szExt[1];
- }
- else
- {
- find.psz = pNewExt->szExt;
- }
-
- iItem = ListView_FindItem(pNewExt->hwndLV, -1, &find);
- if (iItem >= 0)
- {
- // already exists
- WCHAR szText[256], szFormat[256], szTitle[64], szFileType[64];
-
- // get file type
- LV_ITEM item;
- ZeroMemory(&item, sizeof(item));
- item.mask = LVIF_TEXT;
- item.pszText = szFileType;
- item.cchTextMax = _countof(szFileType);
- item.iItem = iItem;
- item.iSubItem = 1;
- ListView_GetItem(pNewExt->hwndLV, &item);
-
- // get text
- LoadStringW(shell32_hInstance, IDS_NEWEXT_ALREADY_ASSOC, szFormat, _countof(szFormat));
- szText[_countof(szFormat) - 1] = 0;
- StringCchPrintfW(szText, _countof(szText), szFormat, find.psz, szFileType, find.psz, szFileType);
-
- // get title
- LoadStringW(shell32_hInstance, IDS_NEWEXT_EXT_IN_USE, szTitle, _countof(szTitle));
- szTitle[_countof(szTitle) - 1] = 0;
-
- if (MessageBoxW(hwndDlg, szText, szTitle, MB_ICONWARNING | MB_YESNO) == IDNO)
- {
- return FALSE;
- }
-
- // Delete the extension
- CStringW strExt(L".");
- strExt += find.psz;
- strExt.MakeLower();
- DeleteExt(hwndDlg, strExt);
-
- // Delete the item
- ListView_DeleteItem(pNewExt->hwndLV, iItem);
- }
-
- EndDialog(hwndDlg, IDOK);
- return TRUE;
-}
-
-// IDD_NEWEXTENSION dialog
-INT_PTR
-CALLBACK
-NewExtensionDlgProc(
- HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- static NEWEXT_DIALOG *s_pNewExt = NULL;
-
- switch (uMsg)
- {
- case WM_INITDIALOG:
- s_pNewExt = (NEWEXT_DIALOG *)lParam;
- NewExtDlg_OnInitDialog(hwndDlg, s_pNewExt);
- return TRUE;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK:
- NewExtDlg_OnOK(hwndDlg, s_pNewExt);
- break;
- case IDCANCEL:
- EndDialog(hwndDlg, IDCANCEL);
- break;
- case IDC_NEWEXT_ADVANCED:
- s_pNewExt->bAdvanced = !s_pNewExt->bAdvanced;
- NewExtDlg_OnAdvanced(hwndDlg, s_pNewExt);
- break;
- }
- break;
- }
- return 0;
-}
-
-static BOOL
-FileTypesDlg_AddExt(HWND hwndDlg, LPCWSTR pszExt, LPCWSTR pszFileType)
-{
- DWORD dwValue = 1;
- HKEY hKey;
- WCHAR szKey[13]; // max. "ft4294967295" + "\0"
- LONG nResult;
-
- // Search the next "ft%06u" key name
- do
- {
- StringCchPrintfW(szKey, _countof(szKey), TEXT("ft%06u"), dwValue);
-
- nResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hKey);
- if (nResult != ERROR_SUCCESS)
- break;
-
- RegCloseKey(hKey);
- ++dwValue;
- } while (dwValue != 0);
-
- RegCloseKey(hKey);
-
- if (dwValue == 0)
- return FALSE;
-
- // Create new "ft%06u" key
- nResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, szKey, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL);
- if (ERROR_SUCCESS != nResult)
- return FALSE;
-
- RegCloseKey(hKey);
-
- // Create the ".ext" key
- WCHAR szExt[16];
- if (*pszExt == L'.')
- ++pszExt;
- StringCchPrintfW(szExt, _countof(szExt), TEXT(".%s"), pszExt);
- CharLowerW(szExt);
- nResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, szExt, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL);
- CharUpperW(szExt);
- if (ERROR_SUCCESS != nResult)
- return FALSE;
-
- // Set the default value of ".ext" to "ft%06u"
- DWORD dwSize = (lstrlen(szKey) + 1) * sizeof(WCHAR);
- RegSetValueExW(hKey, NULL, 0, REG_SZ, (BYTE *)szKey, dwSize);
-
- RegCloseKey(hKey);
-
- // Make up the file type name
- WCHAR szFile[100], szFileFormat[100];
- LoadStringW(shell32_hInstance, IDS_FILE_EXT_TYPE, szFileFormat, _countof(szFileFormat));
- szFile[_countof(szFileFormat) - 1] = 0;
- StringCchPrintfW(szFile, _countof(szFile), szFileFormat, &szExt[1]);
-
- // Insert an item to the listview
- HWND hListView = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
- INT iItem = ListView_GetItemCount(hListView);
- if (!InsertFileType(hListView, szExt, iItem, szFile))
- return FALSE;
-
- LV_ITEM item;
- ZeroMemory(&item, sizeof(item));
- item.mask = LVIF_STATE | LVIF_TEXT;
- item.iItem = iItem;
- item.state = LVIS_SELECTED | LVIS_FOCUSED;
- item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
- item.pszText = &szExt[1];
- ListView_SetItem(hListView, &item);
-
- item.pszText = szFile;
- item.iSubItem = 1;
- ListView_SetItem(hListView, &item);
-
- ListView_EnsureVisible(hListView, iItem, FALSE);
-
- return TRUE;
-}
-
-static BOOL
-FileTypesDlg_RemoveExt(HWND hwndDlg)
-{
- HWND hListView = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
-
- INT iItem = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
- if (iItem == -1)
- return FALSE;
-
- WCHAR szExt[20];
- szExt[0] = L'.';
- ListView_GetItemText(hListView, iItem, 0, &szExt[1], _countof(szExt) - 1);
- CharLowerW(szExt);
-
- DeleteExt(hwndDlg, szExt);
- ListView_DeleteItem(hListView, iItem);
- return TRUE;
-}
-
-static void
-FileTypesDlg_OnItemChanging(HWND hwndDlg, PFOLDER_FILE_TYPE_ENTRY pEntry)
-{
- WCHAR Buffer[255];
- static HBITMAP s_hbmProgram = NULL;
-
- // format buffer and set groupbox text
- CStringW strFormat(MAKEINTRESOURCEW(IDS_FILE_DETAILS));
- StringCchPrintfW(Buffer, _countof(Buffer), strFormat, &pEntry->FileExtension[1]);
- SetDlgItemTextW(hwndDlg, IDC_FILETYPES_DETAILS_GROUPBOX, Buffer);
-
- // format buffer and set description
- strFormat.LoadString(IDS_FILE_DETAILSADV);
- StringCchPrintfW(Buffer, _countof(Buffer), strFormat,
- &pEntry->FileExtension[1], pEntry->FileDescription,
- pEntry->FileDescription);
- SetDlgItemTextW(hwndDlg, IDC_FILETYPES_DESCRIPTION, Buffer);
-
- // delete previous program image
- if (s_hbmProgram)
- {
- DeleteObject(s_hbmProgram);
- s_hbmProgram = NULL;
- }
-
- // set program image
- HICON hIconSm = NULL;
- ExtractIconExW(pEntry->ProgramPath, 0, NULL, &hIconSm, 1);
- s_hbmProgram = BitmapFromIcon(hIconSm, 16, 16);
- DestroyIcon(hIconSm);
- SendDlgItemMessageW(hwndDlg, IDC_FILETYPES_ICON, STM_SETIMAGE, IMAGE_BITMAP, LPARAM(s_hbmProgram));
-
- // set program name
- if (pEntry->AppName[0])
- SetDlgItemTextW(hwndDlg, IDC_FILETYPES_APPNAME, pEntry->AppName);
- else
- SetDlgItemTextW(hwndDlg, IDC_FILETYPES_APPNAME, L"ReactOS");
-
- /* Enable the Delete button */
- if (pEntry->EditFlags & 0x00000010) // FTA_NoRemove
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILETYPES_DELETE), FALSE);
- else
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILETYPES_DELETE), TRUE);
-}
-
-// IDD_FOLDER_OPTIONS_FILETYPES dialog
-INT_PTR
-CALLBACK
-FolderOptionsFileTypesDlg(
- HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- LPNMLISTVIEW lppl;
- PFOLDER_FILE_TYPE_ENTRY pItem;
- OPENASINFO Info;
- NEWEXT_DIALOG newext;
-
- switch(uMsg)
- {
- case WM_INITDIALOG:
- 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, IDC_FILETYPES_DELETE), FALSE);
- return TRUE;
-
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case IDC_FILETYPES_NEW:
- newext.hwndLV = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
- if (IDOK == DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_NEWEXTENSION),
- hwndDlg, NewExtensionDlgProc, (LPARAM)&newext))
- {
- FileTypesDlg_AddExt(hwndDlg, newext.szExt, newext.szFileType);
- }
- break;
- case IDC_FILETYPES_DELETE:
- {
- CStringW strRemoveExt(MAKEINTRESOURCEW(IDS_REMOVE_EXT));
- CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
- if (MessageBoxW(hwndDlg, strRemoveExt, strTitle, MB_ICONQUESTION | MB_YESNO) == IDYES)
- {
- FileTypesDlg_RemoveExt(hwndDlg);
- }
- }
- break;
- case IDC_FILETYPES_CHANGE:
- pItem = GetListViewEntry(GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW));
- if (pItem)
- {
- Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT;
- Info.pcszClass = pItem->FileExtension;
- SHOpenWithDialog(hwndDlg, &Info);
- }
- break;
- }
- break;
-
- case WM_NOTIFY:
- lppl = (LPNMLISTVIEW) lParam;
- switch (lppl->hdr.code)
- {
- case LVN_DELETEALLITEMS:
- return FALSE; // send LVN_DELETEITEM
-
- case LVN_DELETEITEM:
- pItem = GetListViewEntry(lppl->hdr.hwndFrom, lppl->iItem);
- if (pItem)
- {
- DestroyIcon(pItem->hIconLarge);
- DestroyIcon(pItem->hIconSmall);
- HeapFree(GetProcessHeap(), 0, pItem);
- }
- return FALSE;
-
- case LVN_ITEMCHANGING:
- pItem = GetListViewEntry(lppl->hdr.hwndFrom, lppl->iItem);
- if (!pItem)
- return TRUE;
-
- if (!(lppl->uOldState & LVIS_FOCUSED) && (lppl->uNewState & LVIS_FOCUSED))
- {
- FileTypesDlg_OnItemChanging(hwndDlg, pItem);
- }
- break;
-
- case PSN_SETACTIVE:
- /* On page activation, set the focus to the listview */
- SetFocus(GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW));
- break;
- }
- break;
- }
-
- return FALSE;
-}
-
-static
-VOID
-ShowFolderOptionsDialog(HWND hWnd, HINSTANCE hInst)
-{
- PROPSHEETHEADERW pinfo;
- HPROPSHEETPAGE hppages[3];
- HPROPSHEETPAGE hpage;
- UINT num_pages = 0;
- WCHAR szOptions[100];
-
- hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL, FolderOptionsGeneralDlg, 0, NULL);
- if (hpage)
- hppages[num_pages++] = hpage;
-
- hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW, FolderOptionsViewDlg, 0, NULL);
- if (hpage)
- hppages[num_pages++] = hpage;
-
- hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES, FolderOptionsFileTypesDlg, 0, NULL);
- if (hpage)
- hppages[num_pages++] = hpage;
-
- szOptions[0] = L'\0';
- LoadStringW(shell32_hInstance, IDS_FOLDER_OPTIONS, szOptions, sizeof(szOptions) / sizeof(WCHAR));
- szOptions[(sizeof(szOptions)/sizeof(WCHAR))-1] = L'\0';
-
- memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW));
- pinfo.dwSize = sizeof(PROPSHEETHEADERW);
- pinfo.dwFlags = PSH_NOCONTEXTHELP;
- pinfo.nPages = num_pages;
- pinfo.phpage = hppages;
- pinfo.pszCaption = szOptions;
-
- PropertySheetW(&pinfo);
-}
-
-static
-VOID
-Options_RunDLLCommon(HWND hWnd, HINSTANCE hInst, int fOptions, DWORD nCmdShow)
-{
- switch(fOptions)
- {
- case 0:
- ShowFolderOptionsDialog(hWnd, hInst);
- break;
- case 1:
- // show taskbar options dialog
- FIXME("notify explorer to show taskbar options dialog");
- //PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0);
- break;
default:
FIXME("unrecognized options id %d\n", fOptions);
}
/*************************************************************************
* Options_RunDLL (SHELL32.@)
*/
-EXTERN_C VOID WINAPI Options_RunDLL(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
+EXTERN_C VOID WINAPI
+Options_RunDLL(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
{
Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow);
}
/*************************************************************************
* Options_RunDLLA (SHELL32.@)
*/
-EXTERN_C VOID WINAPI Options_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
+EXTERN_C VOID WINAPI
+Options_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
{
Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow);
}
/*************************************************************************
* Options_RunDLLW (SHELL32.@)
*/
-EXTERN_C VOID WINAPI Options_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow)
+EXTERN_C VOID WINAPI
+Options_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow)
{
Options_RunDLLCommon(hWnd, hInst, StrToIntW(cmd), nCmdShow);
}