https://git.reactos.org/?p=reactos.git;a=commitdiff;h=698cbc6184722f29389cc…
commit 698cbc6184722f29389ccd75ca96d88d6cd4b010
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Jun 6 21:04:50 2018 +0900
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Wed Jun 6 14:04:50 2018 +0200
[SHELL32] Split dialogs/folder_options.cpp (#582)
The dialogs/folder_options.cpp source file in shell32 is too big to manage. We will
split it to smaller files.
CORE-12906
---
dll/win32/shell32/CMakeLists.txt | 5 +-
dll/win32/shell32/dialogs/filetypes.cpp | 1778 ++++++++++++++++
dll/win32/shell32/dialogs/folder_options.cpp | 2934 +-------------------------
dll/win32/shell32/dialogs/folder_options.h | 55 +
dll/win32/shell32/dialogs/general.cpp | 147 ++
dll/win32/shell32/dialogs/view.cpp | 985 +++++++++
dll/win32/shell32/lang/bg-BG.rc | 8 +-
dll/win32/shell32/lang/ca-ES.rc | 8 +-
dll/win32/shell32/lang/cs-CZ.rc | 8 +-
dll/win32/shell32/lang/da-DK.rc | 8 +-
dll/win32/shell32/lang/de-DE.rc | 8 +-
dll/win32/shell32/lang/el-GR.rc | 8 +-
dll/win32/shell32/lang/en-GB.rc | 8 +-
dll/win32/shell32/lang/en-US.rc | 8 +-
dll/win32/shell32/lang/es-ES.rc | 8 +-
dll/win32/shell32/lang/et-EE.rc | 8 +-
dll/win32/shell32/lang/fi-FI.rc | 8 +-
dll/win32/shell32/lang/fr-FR.rc | 8 +-
dll/win32/shell32/lang/he-IL.rc | 8 +-
dll/win32/shell32/lang/hu-HU.rc | 8 +-
dll/win32/shell32/lang/it-IT.rc | 8 +-
dll/win32/shell32/lang/ja-JP.rc | 8 +-
dll/win32/shell32/lang/ko-KR.rc | 8 +-
dll/win32/shell32/lang/nl-NL.rc | 8 +-
dll/win32/shell32/lang/no-NO.rc | 8 +-
dll/win32/shell32/lang/pl-PL.rc | 8 +-
dll/win32/shell32/lang/pt-BR.rc | 8 +-
dll/win32/shell32/lang/pt-PT.rc | 8 +-
dll/win32/shell32/lang/ro-RO.rc | 8 +-
dll/win32/shell32/lang/ru-RU.rc | 8 +-
dll/win32/shell32/lang/sk-SK.rc | 8 +-
dll/win32/shell32/lang/sl-SI.rc | 10 +-
dll/win32/shell32/lang/sq-AL.rc | 8 +-
dll/win32/shell32/lang/sv-SE.rc | 8 +-
dll/win32/shell32/lang/tr-TR.rc | 8 +-
dll/win32/shell32/lang/uk-UA.rc | 8 +-
dll/win32/shell32/lang/zh-CN.rc | 8 +-
dll/win32/shell32/lang/zh-TW.rc | 8 +-
dll/win32/shell32/precomp.h | 1 +
dll/win32/shell32/shresdef.h | 6 +
sdk/include/psdk/shlobj.h | 4 +
41 files changed, 3158 insertions(+), 3015 deletions(-)
diff --git a/dll/win32/shell32/CMakeLists.txt b/dll/win32/shell32/CMakeLists.txt
index 76ebf226e3..65d5f0e3b8 100644
--- a/dll/win32/shell32/CMakeLists.txt
+++ b/dll/win32/shell32/CMakeLists.txt
@@ -31,10 +31,13 @@ list(APPEND SOURCE
dialogs/dialogs.cpp
dialogs/drive.cpp
dialogs/drvdefext.cpp
- dialogs/folder_options.cpp
dialogs/filedefext.cpp
+ dialogs/filetypes.cpp
+ dialogs/folder_options.cpp
dialogs/fprop.cpp
+ dialogs/general.cpp
dialogs/recycler_prop.cpp
+ dialogs/view.cpp
CDropTargetHelper.cpp
CEnumIDListBase.cpp
CExtractIcon.cpp
diff --git a/dll/win32/shell32/dialogs/filetypes.cpp
b/dll/win32/shell32/dialogs/filetypes.cpp
new file mode 100644
index 0000000000..8c00df723e
--- /dev/null
+++ b/dll/win32/shell32/dialogs/filetypes.cpp
@@ -0,0 +1,1778 @@
+/*
+ * 'File Types' tab property sheet of Folder Options
+ *
+ * Copyright 2007 Johannes Anderwald <johannes.anderwald(a)reactos.org>
+ * Copyright 2016-2018 Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "precomp.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL (fprop);
+
+// DefaultIcon = %SystemRoot%\system32\SHELL32.dll,-210
+// Verbs: Open / RunAs
+// Cmd: rundll32.exe shell32.dll,Options_RunDLL 0
+
+/////////////////////////////////////////////////////////////////////////////
+
+typedef struct FILE_TYPE_ENTRY
+{
+ WCHAR FileExtension[30];
+ WCHAR FileDescription[100];
+ WCHAR ClassKey[MAX_PATH];
+ WCHAR ClassName[64];
+ DWORD EditFlags;
+ WCHAR AppName[64];
+ HICON hIconLarge;
+ HICON hIconSmall;
+ WCHAR ProgramPath[MAX_PATH];
+ WCHAR IconPath[MAX_PATH];
+ INT nIconIndex;
+} FILE_TYPE_ENTRY, *PFILE_TYPE_ENTRY;
+
+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(PFILE_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(PFILE_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;
+
+ Entry->nIconIndex = PathParseIconLocationW(szLocation);
+ StringCbCopyW(Entry->IconPath, sizeof(Entry->IconPath), szLocation);
+ Entry->hIconLarge = DoExtractIcon(Entry, szLocation, Entry->nIconIndex,
FALSE);
+ Entry->hIconSmall = DoExtractIcon(Entry, szLocation, Entry->nIconIndex, TRUE);
+}
+
+static BOOL
+GetFileTypeIconsEx(PFILE_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));
+ INT cx = GetSystemMetrics(SM_CXSMICON);
+ INT cy = GetSystemMetrics(SM_CYSMICON);
+ Entry->hIconSmall = HICON(LoadImageW(shell32_hInstance,
MAKEINTRESOURCEW(IDI_SHELL_EXE),
+ IMAGE_ICON, cx, cy, 0));
+ StringCbCopyW(Entry->IconPath, sizeof(Entry->IconPath), g_pszShell32);
+ Entry->nIconIndex = -IDI_SHELL_EXE;
+ }
+ 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, PFILE_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 void
+SetFileTypeEntryDefaultIcon(PFILE_TYPE_ENTRY Entry)
+{
+ 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));
+ StringCbCopyW(Entry->IconPath, sizeof(Entry->IconPath), g_pszShell32);
+ Entry->nIconIndex = -IDI_SHELL_FOLDER_OPTIONS;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// EditTypeDlg
+
+#define LISTBOX_MARGIN 2
+
+typedef struct EDITTYPE_DIALOG
+{
+ HWND hwndLV;
+ PFILE_TYPE_ENTRY pEntry;
+ CSimpleMap<CStringW, CStringW> CommandLineMap;
+ WCHAR szIconPath[MAX_PATH];
+ INT nIconIndex;
+ WCHAR szDefaultVerb[64];
+} EDITTYPE_DIALOG, *PEDITTYPE_DIALOG;
+
+static void
+EditTypeDlg_OnChangeIcon(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
+{
+ WCHAR szPath[MAX_PATH];
+ INT IconIndex;
+
+ ExpandEnvironmentStringsW(pEditType->szIconPath, szPath, _countof(szPath));
+ IconIndex = pEditType->nIconIndex;
+ if (PickIconDlg(hwndDlg, szPath, _countof(szPath), &IconIndex))
+ {
+ // replace Windows directory with "%SystemRoot%" (for portability)
+ WCHAR szWinDir[MAX_PATH];
+ GetWindowsDirectoryW(szWinDir, _countof(szWinDir));
+ if (wcsstr(szPath, szWinDir) == 0)
+ {
+ CStringW str(L"%SystemRoot%");
+ str += &szPath[wcslen(szWinDir)];
+ StringCbCopyW(szPath, sizeof(szPath), LPCWSTR(str));
+ }
+
+ // update FILE_TYPE_ENTRY
+ PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
+ DestroyIcon(pEntry->hIconLarge);
+ DestroyIcon(pEntry->hIconSmall);
+ pEntry->hIconLarge = DoExtractIcon(pEntry, szPath, IconIndex, FALSE);
+ pEntry->hIconSmall = DoExtractIcon(pEntry, szPath, IconIndex, TRUE);
+
+ // update EDITTYPE_DIALOG
+ StringCbCopyW(pEditType->szIconPath, sizeof(pEditType->szIconPath),
szPath);
+ pEditType->nIconIndex = IconIndex;
+
+ // set icon to dialog
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_ICON, STM_SETICON,
(WPARAM)pEntry->hIconLarge, 0);
+ }
+}
+
+static BOOL
+EditTypeDlg_OnDrawItem(HWND hwndDlg, LPDRAWITEMSTRUCT pDraw, PEDITTYPE_DIALOG pEditType)
+{
+ WCHAR szText[64];
+ HFONT hFont, hFont2;
+
+ if (!pDraw)
+ return FALSE;
+
+ // fill rect and set colors
+ if (pDraw->itemState & ODS_SELECTED)
+ {
+ FillRect(pDraw->hDC, &pDraw->rcItem, HBRUSH(COLOR_HIGHLIGHT + 1));
+ SetTextColor(pDraw->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+ SetBkColor(pDraw->hDC, GetSysColor(COLOR_HIGHLIGHT));
+ }
+ else
+ {
+ FillRect(pDraw->hDC, &pDraw->rcItem, HBRUSH(COLOR_WINDOW + 1));
+ SetTextColor(pDraw->hDC, GetSysColor(COLOR_WINDOWTEXT));
+ SetBkColor(pDraw->hDC, GetSysColor(COLOR_WINDOW));
+ }
+
+ // get listbox text
+ HWND hwndListBox = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
+ SendMessageW(hwndListBox, LB_GETTEXT, pDraw->itemID, (LPARAM)szText);
+
+ // is it default?
+ hFont = (HFONT)SendMessageW(hwndListBox, WM_GETFONT, 0, 0);
+ if (lstrcmpiW(pEditType->szDefaultVerb, szText) == 0)
+ {
+ // default. set bold
+ LOGFONTW lf;
+ GetObject(hFont, sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ hFont2 = CreateFontIndirectW(&lf);
+ if (hFont2)
+ {
+ HGDIOBJ hFontOld = SelectObject(pDraw->hDC, hFont2);
+ InflateRect(&pDraw->rcItem, -LISTBOX_MARGIN, -LISTBOX_MARGIN);
+ DrawTextW(pDraw->hDC, szText, -1, &pDraw->rcItem,
+ DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
+ InflateRect(&pDraw->rcItem, LISTBOX_MARGIN, LISTBOX_MARGIN);
+ SelectObject(pDraw->hDC, hFontOld);
+ DeleteObject(hFont2);
+ }
+ }
+ else
+ {
+ // non-default
+ InflateRect(&pDraw->rcItem, -LISTBOX_MARGIN, -LISTBOX_MARGIN);
+ DrawTextW(pDraw->hDC, szText, -1, &pDraw->rcItem,
+ DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
+ InflateRect(&pDraw->rcItem, LISTBOX_MARGIN, LISTBOX_MARGIN);
+ }
+
+ // draw focus rect
+ if (pDraw->itemState & ODS_FOCUS)
+ {
+ DrawFocusRect(pDraw->hDC, &pDraw->rcItem);
+ }
+ return TRUE;
+}
+
+static BOOL
+EditTypeDlg_OnMeasureItem(HWND hwndDlg, LPMEASUREITEMSTRUCT pMeasure, PEDITTYPE_DIALOG
pEditType)
+{
+ if (!pMeasure)
+ return FALSE;
+
+ HWND hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
+
+ HDC hDC = GetDC(hwndLB);
+ if (hDC)
+ {
+ TEXTMETRICW tm;
+ GetTextMetricsW(hDC, &tm);
+ pMeasure->itemHeight = tm.tmHeight + LISTBOX_MARGIN * 2;
+ ReleaseDC(hwndLB, hDC);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// NewExtDlg
+
+typedef struct NEWEXT_DIALOG
+{
+ HWND hwndLV;
+ RECT rcDlg;
+ BOOL bAdvanced;
+ INT dy;
+ WCHAR szExt[16];
+ WCHAR szFileType[64];
+} NEWEXT_DIALOG, *PNEWEXT_DIALOG;
+
+static VOID
+NewExtDlg_OnAdvanced(HWND hwndDlg, PNEWEXT_DIALOG pNewExt)
+{
+ // If "Advanced" button was clicked, then we shrink or expand the dialog.
+ 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, (LPPOINT)&rc1, 2);
+
+ GetWindowRect(GetDlgItem(hwndDlg, IDCANCEL), &rc2);
+ MapWindowPoints(NULL, hwndDlg, (LPPOINT)&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);
+
+ CStringW strLeft(MAKEINTRESOURCEW(IDS_NEWEXT_ADVANCED_LEFT));
+ SetDlgItemTextW(hwndDlg, IDC_NEWEXT_ADVANCED, strLeft);
+
+ 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);
+
+ CStringW strRight(MAKEINTRESOURCEW(IDS_NEWEXT_ADVANCED_RIGHT));
+ SetDlgItemTextW(hwndDlg, IDC_NEWEXT_ADVANCED, strRight);
+
+ rc.bottom -= pNewExt->dy;
+
+ CStringW strText(MAKEINTRESOURCEW(IDS_NEWEXT_NEW));
+ SetDlgItemTextW(hwndDlg, IDC_NEWEXT_COMBOBOX, strText);
+ }
+
+ 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, PNEWEXT_DIALOG pNewExt)
+{
+ pNewExt->bAdvanced = FALSE;
+
+ // get window rectangle
+ GetWindowRect(hwndDlg, &pNewExt->rcDlg);
+
+ // get delta Y
+ RECT rc1, rc2;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_NEWEXT_EDIT), &rc1);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_NEWEXT_COMBOBOX), &rc2);
+ pNewExt->dy = rc2.top - rc1.top;
+
+ // initialize
+ CStringW strText(MAKEINTRESOURCEW(IDS_NEWEXT_NEW));
+ SendDlgItemMessageW(hwndDlg, IDC_NEWEXT_COMBOBOX, CB_ADDSTRING, 0,
(LPARAM)(LPCWSTR)strText);
+ SendDlgItemMessageW(hwndDlg, IDC_NEWEXT_COMBOBOX, CB_SETCURSEL, 0, 0);
+ SendDlgItemMessageW(hwndDlg, IDC_NEWEXT_EDIT, EM_SETLIMITTEXT,
_countof(pNewExt->szExt) - 1, 0);
+
+ // shrink it first time
+ NewExtDlg_OnAdvanced(hwndDlg, pNewExt);
+
+ return TRUE;
+}
+
+static BOOL
+NewExtDlg_OnOK(HWND hwndDlg, PNEWEXT_DIALOG pNewExt)
+{
+ LV_FINDINFO find;
+ INT iItem;
+
+ GetDlgItemTextW(hwndDlg, IDC_NEWEXT_EDIT, pNewExt->szExt,
_countof(pNewExt->szExt));
+ StrTrimW(pNewExt->szExt, g_pszSpace);
+ _wcsupr(pNewExt->szExt);
+
+ GetDlgItemTextW(hwndDlg, IDC_NEWEXT_COMBOBOX, pNewExt->szFileType,
_countof(pNewExt->szFileType));
+ StrTrimW(pNewExt->szFileType, g_pszSpace);
+
+ if (pNewExt->szExt[0] == 0)
+ {
+ CStringW strText(MAKEINTRESOURCEW(IDS_NEWEXT_SPECIFY_EXT));
+ CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
+ MessageBoxW(hwndDlg, strText, strTitle, 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
+
+ // get file type
+ WCHAR szFileType[64];
+ 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
+ CStringW strText;
+ strText.Format(IDS_NEWEXT_ALREADY_ASSOC, find.psz, szFileType, find.psz,
szFileType);
+
+ // get title
+ CStringW strTitle;
+ strTitle.LoadString(IDS_NEWEXT_EXT_IN_USE);
+
+ if (MessageBoxW(hwndDlg, strText, strTitle, 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
+static INT_PTR CALLBACK
+NewExtDlgProc(
+ HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ static PNEWEXT_DIALOG s_pNewExt = NULL;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ s_pNewExt = (PNEWEXT_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_InsertToLV(HWND hListView, LPCWSTR szName, INT iItem, LPCWSTR szFile)
+{
+ PFILE_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 = (PFILE_TYPE_ENTRY)HeapAlloc(GetProcessHeap(), 0, sizeof(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;
+ }
+
+ Entry->ClassName[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)
+ {
+ DWORD dwSize = sizeof(Entry->ClassName);
+ RegQueryValueExW(hTemp, NULL, NULL, NULL, LPBYTE(Entry->ClassName),
&dwSize);
+
+ // 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
+ SetFileTypeEntryDefaultIcon(Entry);
+ }
+
+ // 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'
+
+ StringCbPrintf(Entry->FileDescription, sizeof(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 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
+ {
+ StringCbPrintfW(szKey, sizeof(szKey), L"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;
+ StringCbPrintfW(szExt, sizeof(szExt), L".%s", pszExt);
+ _wcslwr(szExt);
+ nResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, szExt, 0, NULL, 0, KEY_WRITE, NULL,
&hKey, NULL);
+ _wcsupr(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, (LPBYTE)szKey, dwSize);
+
+ RegCloseKey(hKey);
+
+ // Make up the file type name
+ WCHAR szFile[100];
+ CStringW strFormat(MAKEINTRESOURCEW(IDS_FILE_EXT_TYPE));
+ StringCbPrintfW(szFile, sizeof(szFile), strFormat, &szExt[1]);
+
+ // Insert an item to the listview
+ HWND hListView = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
+ INT iItem = ListView_GetItemCount(hListView);
+ if (!FileTypesDlg_InsertToLV(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);
+ _wcslwr(szExt);
+
+ DeleteExt(hwndDlg, szExt);
+ ListView_DeleteItem(hListView, iItem);
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// common code of NewActionDlg and EditActionDlg
+
+typedef struct ACTION_DIALOG
+{
+ HWND hwndLB;
+ WCHAR ClassName[64];
+ WCHAR szAction[64];
+ WCHAR szApp[MAX_PATH];
+ BOOL bUseDDE;
+} ACTION_DIALOG, *PACTION_DIALOG;
+
+static void
+ActionDlg_OnBrowse(HWND hwndDlg, PACTION_DIALOG pNewAct, BOOL bEdit = FALSE)
+{
+ WCHAR szFile[MAX_PATH];
+ szFile[0] = 0;
+
+ WCHAR szFilter[MAX_PATH];
+ LoadStringW(shell32_hInstance, IDS_EXE_FILTER, szFilter, _countof(szFilter));
+
+ CStringW strTitle(MAKEINTRESOURCEW(IDS_OPEN_WITH));
+
+ OPENFILENAMEW ofn;
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
+ ofn.hwndOwner = hwndDlg;
+ ofn.lpstrFilter = szFilter;
+ ofn.lpstrFile = szFile;
+ ofn.nMaxFile = _countof(szFile);
+ ofn.lpstrTitle = strTitle;
+ ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST |
OFN_HIDEREADONLY;
+ ofn.lpstrDefExt = L"exe";
+ if (GetOpenFileNameW(&ofn))
+ {
+ if (bEdit)
+ {
+ CStringW str = szFile;
+ str += L" \"%1\"";
+ SetDlgItemTextW(hwndDlg, IDC_ACTION_APP, str);
+ }
+ else
+ {
+ SetDlgItemTextW(hwndDlg, IDC_ACTION_APP, szFile);
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// NewActionDlg
+
+static void
+NewActionDlg_OnOK(HWND hwndDlg, PACTION_DIALOG pNewAct)
+{
+ // check action
+ GetDlgItemTextW(hwndDlg, IDC_ACTION_ACTION, pNewAct->szAction,
_countof(pNewAct->szAction));
+ StrTrimW(pNewAct->szAction, g_pszSpace);
+ if (pNewAct->szAction[0] == 0)
+ {
+ // action was empty, error
+ HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_ACTION);
+ SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
+ SetFocus(hwndCtrl);
+ CStringW strText(MAKEINTRESOURCEW(IDS_SPECIFY_ACTION));
+ CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
+ MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
+ return;
+ }
+
+ // check app
+ GetDlgItemTextW(hwndDlg, IDC_ACTION_APP, pNewAct->szApp,
_countof(pNewAct->szApp));
+ StrTrimW(pNewAct->szApp, g_pszSpace);
+ if (pNewAct->szApp[0] == 0 ||
+ GetFileAttributesW(pNewAct->szApp) == INVALID_FILE_ATTRIBUTES)
+ {
+ // app was empty or invalid
+ HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_APP);
+ SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
+ SetFocus(hwndCtrl);
+ CStringW strText(MAKEINTRESOURCEW(IDS_INVALID_PROGRAM));
+ CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
+ MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
+ return;
+ }
+
+ EndDialog(hwndDlg, IDOK);
+}
+
+// IDD_ACTION
+static INT_PTR CALLBACK
+NewActionDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static PACTION_DIALOG s_pNewAct = NULL;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ s_pNewAct = (PACTION_DIALOG)lParam;
+ s_pNewAct->bUseDDE = FALSE;
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ACTION_USE_DDE), FALSE);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ NewActionDlg_OnOK(hwndDlg, s_pNewAct);
+ break;
+
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ break;
+
+ case IDC_ACTION_BROWSE:
+ ActionDlg_OnBrowse(hwndDlg, s_pNewAct, FALSE);
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// EditActionDlg
+
+static void
+EditActionDlg_OnOK(HWND hwndDlg, PACTION_DIALOG pEditAct)
+{
+ // check action
+ GetDlgItemTextW(hwndDlg, IDC_ACTION_ACTION, pEditAct->szAction,
_countof(pEditAct->szAction));
+ StrTrimW(pEditAct->szAction, g_pszSpace);
+ if (pEditAct->szAction[0] == 0)
+ {
+ // action was empty. show error
+ HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_ACTION);
+ SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
+ SetFocus(hwndCtrl);
+ CStringW strText(MAKEINTRESOURCEW(IDS_SPECIFY_ACTION));
+ CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
+ MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
+ }
+
+ // check app
+ GetDlgItemTextW(hwndDlg, IDC_ACTION_APP, pEditAct->szApp,
_countof(pEditAct->szApp));
+ StrTrimW(pEditAct->szApp, g_pszSpace);
+ if (pEditAct->szApp[0] == 0)
+ {
+ // app was empty. show error
+ HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_APP);
+ SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
+ SetFocus(hwndCtrl);
+ CStringW strText(MAKEINTRESOURCEW(IDS_INVALID_PROGRAM));
+ CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
+ MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
+ }
+
+ EndDialog(hwndDlg, IDOK);
+}
+
+// IDD_ACTION
+static INT_PTR CALLBACK
+EditActionDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static PACTION_DIALOG s_pEditAct = NULL;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ s_pEditAct = (PACTION_DIALOG)lParam;
+ s_pEditAct->bUseDDE = FALSE;
+ SetDlgItemTextW(hwndDlg, IDC_ACTION_ACTION, s_pEditAct->szAction);
+ SetDlgItemTextW(hwndDlg, IDC_ACTION_APP, s_pEditAct->szApp);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ACTION_USE_DDE), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ACTION_ACTION), FALSE);
+ {
+ // set title
+ CStringW str(MAKEINTRESOURCEW(IDS_EDITING_ACTION));
+ str += s_pEditAct->ClassName;
+ SetWindowTextW(hwndDlg, str);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ EditActionDlg_OnOK(hwndDlg, s_pEditAct);
+ break;
+
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ break;
+
+ case IDC_ACTION_BROWSE:
+ ActionDlg_OnBrowse(hwndDlg, s_pEditAct, TRUE);
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// EditTypeDlg
+
+static BOOL
+EditTypeDlg_UpdateEntryIcon(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
+ LPCWSTR IconPath, INT IconIndex)
+{
+ PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
+
+ BOOL bIconSet = FALSE;
+ if (IconPath && IconPath[0])
+ {
+ DestroyIcon(pEntry->hIconLarge);
+ DestroyIcon(pEntry->hIconSmall);
+ pEntry->hIconLarge = DoExtractIcon(pEntry, IconPath, IconIndex, FALSE);
+ pEntry->hIconSmall = DoExtractIcon(pEntry, IconPath, IconIndex, TRUE);
+
+ bIconSet = (pEntry->hIconLarge && pEntry->hIconSmall);
+ }
+ if (bIconSet)
+ {
+ StringCbCopyW(pEntry->IconPath, sizeof(pEntry->IconPath), IconPath);
+ pEntry->nIconIndex = IconIndex;
+ }
+ else
+ {
+ SetFileTypeEntryDefaultIcon(pEntry);
+ }
+
+ HWND hListView = pEditType->hwndLV;
+ HIMAGELIST himlLarge = ListView_GetImageList(hListView, LVSIL_NORMAL);
+ HIMAGELIST himlSmall = ListView_GetImageList(hListView, LVSIL_SMALL);
+
+ INT iLargeImage = ImageList_AddIcon(himlLarge, pEntry->hIconLarge);
+ INT iSmallImage = ImageList_AddIcon(himlSmall, pEntry->hIconSmall);
+ ASSERT(iLargeImage == iSmallImage);
+
+ INT iItem = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
+ if (iItem != -1)
+ {
+ LV_ITEMW Item = { LVIF_IMAGE, iItem };
+ Item.iImage = iSmallImage;
+ ListView_SetItem(hListView, &Item);
+ }
+ return TRUE;
+}
+
+static BOOL
+EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
+ LPCWSTR ClassKey, LPCWSTR ClassName, INT cchName)
+{
+ PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
+
+ if (ClassKey[0] == 0)
+ return FALSE;
+
+ // create or open class key
+ HKEY hClassKey;
+ if (RegCreateKeyExW(HKEY_CLASSES_ROOT, ClassKey, 0, NULL, 0, KEY_WRITE, NULL,
+ &hClassKey, NULL) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ // create "DefaultIcon" key
+ if (pEntry->IconPath[0])
+ {
+ HKEY hDefaultIconKey;
+ if (RegCreateKeyExW(hClassKey, L"DefaultIcon", 0, NULL, 0, KEY_WRITE,
NULL,
+ &hDefaultIconKey, NULL) == ERROR_SUCCESS)
+ {
+ WCHAR szText[MAX_PATH];
+ StringCbPrintfW(szText, sizeof(szText), L"%s,%d",
+ pEntry->IconPath, pEntry->nIconIndex);
+
+ // set icon location
+ DWORD dwSize = (lstrlenW(szText) + 1) * sizeof(WCHAR);
+ RegSetValueExW(hDefaultIconKey, NULL, 0, REG_EXPAND_SZ, LPBYTE(szText),
dwSize);
+
+ RegCloseKey(hDefaultIconKey);
+ }
+ }
+
+ // create "shell" key
+ HKEY hShellKey;
+ if (RegCreateKeyExW(hClassKey, L"shell", 0, NULL, 0, KEY_WRITE, NULL,
+ &hShellKey, NULL) != ERROR_SUCCESS)
+ {
+ RegCloseKey(hClassKey);
+ return FALSE;
+ }
+
+ // delete shell commands
+ WCHAR szVerbName[64];
+ DWORD dwIndex = 0;
+ while (RegEnumKeyW(hShellKey, dwIndex, szVerbName, _countof(szVerbName)) ==
ERROR_SUCCESS)
+ {
+ if (pEditType->CommandLineMap.FindKey(szVerbName) == -1)
+ {
+ // doesn't exist in CommandLineMap, then delete it
+ if (SHDeleteKeyW(hShellKey, szVerbName) == ERROR_SUCCESS)
+ {
+ --dwIndex;
+ }
+ }
+ ++dwIndex;
+ }
+
+ // set default action
+ RegSetValueExW(hShellKey, NULL, 0, REG_SZ,
+ LPBYTE(pEditType->szDefaultVerb),
sizeof(pEditType->szDefaultVerb));
+
+ // write shell commands
+ const INT nCount = pEditType->CommandLineMap.GetSize();
+ for (INT i = 0; i < nCount; ++i)
+ {
+ CStringW& key = pEditType->CommandLineMap.GetKeyAt(i);
+ CStringW& value = pEditType->CommandLineMap.GetValueAt(i);
+
+ // create verb key
+ HKEY hVerbKey;
+ if (RegCreateKeyExW(hShellKey, key, 0, NULL, 0, KEY_WRITE, NULL,
+ &hVerbKey, NULL) == ERROR_SUCCESS)
+ {
+ // create command key
+ HKEY hCommandKey;
+ if (RegCreateKeyExW(hVerbKey, L"command", 0, NULL, 0, KEY_WRITE,
NULL,
+ &hCommandKey, NULL) == ERROR_SUCCESS)
+ {
+ // write the default value
+ DWORD dwSize = (value.GetLength() + 1) * sizeof(WCHAR);
+ RegSetValueExW(hCommandKey, NULL, 0, REG_EXPAND_SZ,
LPBYTE(LPCWSTR(value)), dwSize);
+
+ RegCloseKey(hCommandKey);
+ }
+
+ RegCloseKey(hVerbKey);
+ }
+ }
+
+ // set class name to class key
+ RegSetValueExW(hClassKey, NULL, 0, REG_SZ, LPBYTE(ClassName), cchName);
+
+ RegCloseKey(hShellKey);
+ RegCloseKey(hClassKey);
+
+ return TRUE;
+}
+
+static BOOL
+EditTypeDlg_ReadClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType, LPCWSTR ClassKey)
+{
+ // open class key
+ HKEY hClassKey;
+ if (RegOpenKeyExW(HKEY_CLASSES_ROOT, ClassKey, 0, KEY_READ, &hClassKey) !=
ERROR_SUCCESS)
+ return FALSE;
+
+ // open "shell" key
+ HKEY hShellKey;
+ if (RegOpenKeyExW(hClassKey, L"shell", 0, KEY_READ, &hShellKey) !=
ERROR_SUCCESS)
+ {
+ RegCloseKey(hClassKey);
+ return FALSE;
+ }
+
+ WCHAR DefaultVerb[64];
+ DWORD dwSize = sizeof(DefaultVerb);
+ if (RegQueryValueExW(hShellKey, NULL, NULL, NULL,
+ LPBYTE(DefaultVerb), &dwSize) == ERROR_SUCCESS)
+ {
+ StringCbCopyW(pEditType->szDefaultVerb, sizeof(pEditType->szDefaultVerb),
DefaultVerb);
+ }
+ else
+ {
+ StringCbCopyW(pEditType->szDefaultVerb, sizeof(pEditType->szDefaultVerb),
L"open");
+ }
+
+ // enumerate shell verbs
+ WCHAR szVerbName[64];
+ DWORD dwIndex = 0;
+ while (RegEnumKeyW(hShellKey, dwIndex, szVerbName, _countof(szVerbName)) ==
ERROR_SUCCESS)
+ {
+ // open verb key
+ HKEY hVerbKey;
+ LONG nResult = RegOpenKeyExW(hShellKey, szVerbName, 0, KEY_READ, &hVerbKey);
+ if (nResult == ERROR_SUCCESS)
+ {
+ // open command key
+ HKEY hCommandKey;
+ nResult = RegOpenKeyExW(hVerbKey, L"command", 0, KEY_READ,
&hCommandKey);
+ if (nResult == ERROR_SUCCESS)
+ {
+ // get command line
+ WCHAR szValue[MAX_PATH + 32];
+ dwSize = sizeof(szValue);
+ nResult = RegQueryValueExW(hCommandKey, NULL, NULL, NULL,
LPBYTE(szValue), &dwSize);
+ if (nResult == ERROR_SUCCESS)
+ {
+ pEditType->CommandLineMap.SetAt(szVerbName, szValue);
+ }
+
+ RegCloseKey(hCommandKey);
+ }
+
+ RegCloseKey(hVerbKey);
+ }
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_ADDSTRING, 0,
LPARAM(szVerbName));
+ ++dwIndex;
+ }
+
+ RegCloseKey(hShellKey);
+ RegCloseKey(hClassKey);
+
+ return TRUE;
+}
+
+static void
+EditTypeDlg_OnOK(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
+{
+ PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
+
+ // get class name
+ GetDlgItemTextW(hwndDlg, IDC_EDITTYPE_TEXT, pEntry->ClassName,
_countof(pEntry->ClassName));
+ StrTrimW(pEntry->ClassName, g_pszSpace);
+
+ // update entry icon
+ EditTypeDlg_UpdateEntryIcon(hwndDlg, pEditType, pEditType->szIconPath,
pEditType->nIconIndex);
+
+ // write registry
+ EditTypeDlg_WriteClass(hwndDlg, pEditType, pEntry->ClassKey,
pEntry->ClassName,
+ _countof(pEntry->ClassName));
+
+ // update the icon cache
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, NULL, NULL);
+
+ EndDialog(hwndDlg, IDOK);
+}
+
+static BOOL
+EditTypeDlg_OnRemove(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
+{
+ // get current selection
+ INT iItem = SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_GETCURSEL, 0, 0);
+ if (iItem == LB_ERR)
+ return FALSE;
+
+ // ask user for removal
+ CStringW strText(MAKEINTRESOURCEW(IDS_REMOVE_ACTION));
+ CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
+ if (MessageBoxW(hwndDlg, strText, strTitle, MB_ICONINFORMATION | MB_YESNO) == IDNO)
+ return FALSE;
+
+ // get text
+ WCHAR szText[64];
+ szText[0] = 0;
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_GETTEXT, iItem,
(LPARAM)szText);
+ StrTrimW(szText, g_pszSpace);
+
+ // remove it
+ pEditType->CommandLineMap.Remove(szText);
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_DELETESTRING, iItem, 0);
+ return TRUE;
+}
+
+static void
+EditTypeDlg_OnCommand(HWND hwndDlg, UINT id, UINT code, PEDITTYPE_DIALOG pEditType)
+{
+ INT iItem, iIndex;
+ ACTION_DIALOG action;
+ switch (id)
+ {
+ case IDOK:
+ EditTypeDlg_OnOK(hwndDlg, pEditType);
+ break;
+
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ break;
+
+ case IDC_EDITTYPE_CHANGE_ICON:
+ EditTypeDlg_OnChangeIcon(hwndDlg, pEditType);
+ break;
+
+ case IDC_EDITTYPE_NEW:
+ action.bUseDDE = FALSE;
+ action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
+ StringCbPrintfW(action.ClassName, sizeof(action.ClassName),
pEditType->pEntry->ClassName);
+ // open 'New Action' dialog
+ if (IDOK == DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_ACTION),
hwndDlg,
+ NewActionDlgProc, LPARAM(&action)))
+ {
+ if (SendMessageW(action.hwndLB, LB_FINDSTRING, -1,
(LPARAM)action.szAction) != LB_ERR)
+ {
+ // already exists, error
+ HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_ACTION);
+ SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
+ SetFocus(hwndCtrl);
+
+ CStringW strText, strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
+ strText.Format(IDS_ACTION_EXISTS, action.szAction);
+ MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
+ }
+ else
+ {
+ // add it
+ CStringW strCommandLine = action.szApp;
+ strCommandLine += L" \"%1\"";
+ pEditType->CommandLineMap.SetAt(action.szAction, strCommandLine);
+ SendMessageW(action.hwndLB, LB_ADDSTRING, 0,
LPARAM(action.szAction));
+ if (SendMessageW(action.hwndLB, LB_GETCOUNT, 0, 0) == 1)
+ {
+ // set default
+ StringCbCopyW(pEditType->szDefaultVerb,
sizeof(pEditType->szDefaultVerb), action.szAction);
+ InvalidateRect(action.hwndLB, NULL, TRUE);
+ }
+ }
+ }
+ break;
+
+ case IDC_EDITTYPE_LISTBOX:
+ if (code == LBN_SELCHANGE)
+ {
+ action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
+ INT iItem = SendMessageW(action.hwndLB, LB_GETCURSEL, 0, 0);
+ SendMessageW(action.hwndLB, LB_GETTEXT, iItem, LPARAM(action.szAction));
+ if (lstrcmpiW(action.szAction, pEditType->szDefaultVerb) == 0)
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SET_DEFAULT), FALSE);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SET_DEFAULT), TRUE);
+ }
+ break;
+ }
+ else if (code != LBN_DBLCLK)
+ {
+ break;
+ }
+ // FALL THROUGH
+
+ case IDC_EDITTYPE_EDIT_BUTTON:
+ action.bUseDDE = FALSE;
+ action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
+ StringCbPrintfW(action.ClassName, sizeof(action.ClassName),
pEditType->pEntry->ClassName);
+ iItem = SendMessageW(action.hwndLB, LB_GETCURSEL, 0, 0);
+ if (iItem == LB_ERR)
+ break;
+
+ // get action
+ SendMessageW(action.hwndLB, LB_GETTEXT, iItem, LPARAM(action.szAction));
+
+ // get app
+ {
+ iIndex = pEditType->CommandLineMap.FindKey(action.szAction);
+ CStringW str = pEditType->CommandLineMap.GetValueAt(iIndex);
+ StringCbCopyW(action.szApp, sizeof(action.szApp), LPCWSTR(str));
+ }
+
+ // open dialog
+ if (IDOK == DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_ACTION),
hwndDlg,
+ EditActionDlgProc, LPARAM(&action)))
+ {
+ SendMessageW(action.hwndLB, LB_DELETESTRING, iItem, 0);
+ SendMessageW(action.hwndLB, LB_INSERTSTRING, iItem,
LPARAM(action.szAction));
+ pEditType->CommandLineMap.SetAt(action.szAction, action.szApp);
+ }
+ break;
+
+ case IDC_EDITTYPE_REMOVE:
+ EditTypeDlg_OnRemove(hwndDlg, pEditType);
+ break;
+
+ case IDC_EDITTYPE_SET_DEFAULT:
+ action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
+ iItem = SendMessageW(action.hwndLB, LB_GETCURSEL, 0, 0);
+ if (iItem == LB_ERR)
+ break;
+
+ SendMessageW(action.hwndLB, LB_GETTEXT, iItem, LPARAM(action.szAction));
+
+ // set default
+ StringCbCopyW(pEditType->szDefaultVerb,
sizeof(pEditType->szDefaultVerb), action.szAction);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SET_DEFAULT), FALSE);
+ InvalidateRect(action.hwndLB, NULL, TRUE);
+ break;
+ }
+}
+
+static BOOL
+EditTypeDlg_OnInitDialog(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
+{
+ PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
+ StringCbCopyW(pEditType->szIconPath, sizeof(pEditType->szIconPath),
pEntry->IconPath);
+ pEditType->nIconIndex = pEntry->nIconIndex;
+ StringCbCopyW(pEditType->szDefaultVerb, sizeof(pEditType->szDefaultVerb),
L"open");
+
+ // set info
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_ICON, STM_SETICON,
(WPARAM)pEntry->hIconLarge, 0);
+ SetDlgItemTextW(hwndDlg, IDC_EDITTYPE_TEXT, pEntry->ClassName);
+ EditTypeDlg_ReadClass(hwndDlg, pEditType, pEntry->ClassKey);
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX), NULL, TRUE);
+
+ // is listbox empty?
+ if (SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_GETCOUNT, 0, 0) == 0)
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_EDIT_BUTTON), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_REMOVE), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SET_DEFAULT), FALSE);
+ }
+ else
+ {
+ // select first item
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_SETCURSEL, 0, 0);
+ }
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SAME_WINDOW), FALSE);
+
+ return TRUE;
+}
+
+// IDD_EDITTYPE
+static INT_PTR CALLBACK
+EditTypeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static PEDITTYPE_DIALOG s_pEditType = NULL;
+ LPDRAWITEMSTRUCT pDraw;
+ LPMEASUREITEMSTRUCT pMeasure;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ s_pEditType = (PEDITTYPE_DIALOG)lParam;
+ return EditTypeDlg_OnInitDialog(hwndDlg, s_pEditType);
+
+ case WM_DRAWITEM:
+ pDraw = LPDRAWITEMSTRUCT(lParam);
+ return EditTypeDlg_OnDrawItem(hwndDlg, pDraw, s_pEditType);
+
+ case WM_MEASUREITEM:
+ pMeasure = LPMEASUREITEMSTRUCT(lParam);
+ return EditTypeDlg_OnMeasureItem(hwndDlg, pMeasure, s_pEditType);
+
+ case WM_COMMAND:
+ EditTypeDlg_OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), s_pEditType);
+ break;
+ }
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// FileTypesDlg
+
+static INT CALLBACK
+FileTypesDlg_CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
+{
+ PFILE_TYPE_ENTRY Entry1, Entry2;
+ int x;
+
+ Entry1 = (PFILE_TYPE_ENTRY)lParam1;
+ Entry2 = (PFILE_TYPE_ENTRY)lParam2;
+
+ x = wcsicmp(Entry1->FileExtension, Entry2->FileExtension);
+ if (x != 0)
+ return x;
+
+ return wcsicmp(Entry1->FileDescription, Entry2->FileDescription);
+}
+
+static VOID
+FileTypesDlg_InitListView(HWND hwndDlg, HWND hListView)
+{
+ RECT clientRect;
+ LVCOLUMNW col;
+ WCHAR szName[50];
+ DWORD dwStyle;
+ INT columnSize = 140;
+
+ if (!LoadStringW(shell32_hInstance, IDS_COLUMN_EXTENSION, szName, _countof(szName)))
+ {
+ // default to english
+ wcscpy(szName, L"Extensions");
+ }
+
+ // make sure its null terminated
+ szName[_countof(szName) - 1] = 0;
+
+ GetClientRect(hListView, &clientRect);
+ ZeroMemory(&col, sizeof(LV_COLUMN));
+ columnSize = 120;
+ 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;
+ SendMessageW(hListView, LVM_INSERTCOLUMNW, 0, (LPARAM)&col);
+
+ if (!LoadStringW(shell32_hInstance, IDS_FILE_TYPES, szName, _countof(szName)))
+ {
+ // 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;
+ SendMessageW(hListView, LVM_INSERTCOLUMNW, 1, (LPARAM)&col);
+
+ // set full select style
+ dwStyle = (DWORD)SendMessage(hListView, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
+ dwStyle = dwStyle | LVS_EX_FULLROWSELECT;
+ SendMessage(hListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
+}
+
+static PFILE_TYPE_ENTRY
+FileTypesDlg_DoList(HWND hwndDlg)
+{
+ HWND hListView;
+ 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.
+ hListView = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
+ ListView_SetImageList(hListView, himlLarge, LVSIL_NORMAL);
+ ListView_SetImageList(hListView, himlSmall, LVSIL_SMALL);
+
+ FileTypesDlg_InitListView(hwndDlg, hListView);
+
+ 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 (FileTypesDlg_InsertToLV(hListView, szName, iItem, szFile))
+ ++iItem;
+ dwName = _countof(szName);
+ }
+
+ // Leave if the list is empty
+ if (iItem == 0)
+ return NULL;
+
+ // sort list
+ ListView_SortItems(hListView, FileTypesDlg_CompareItems, 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(hListView, &lvItem);
+
+ lvItem.mask = LVIF_PARAM;
+ ListView_GetItem(hListView, &lvItem);
+
+ return (PFILE_TYPE_ENTRY)lvItem.lParam;
+}
+
+static inline PFILE_TYPE_ENTRY
+FileTypesDlg_GetEntry(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 (PFILE_TYPE_ENTRY)lvItem.lParam;
+
+ return NULL;
+}
+
+static void
+FileTypesDlg_OnDelete(HWND hwndDlg)
+{
+ 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);
+ }
+}
+
+static void
+FileTypesDlg_OnItemChanging(HWND hwndDlg, PFILE_TYPE_ENTRY pEntry)
+{
+ WCHAR Buffer[255];
+ static HBITMAP s_hbmProgram = NULL;
+
+ // format buffer and set groupbox text
+ CStringW strFormat(MAKEINTRESOURCEW(IDS_FILE_DETAILS));
+ StringCbPrintfW(Buffer, sizeof(Buffer), strFormat,
&pEntry->FileExtension[1]);
+ SetDlgItemTextW(hwndDlg, IDC_FILETYPES_DETAILS_GROUPBOX, Buffer);
+
+ // format buffer and set description
+ strFormat.LoadString(IDS_FILE_DETAILSADV);
+ StringCbPrintfW(Buffer, sizeof(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
+INT_PTR CALLBACK
+FolderOptionsFileTypesDlg(
+ HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ LPNMLISTVIEW lppl;
+ PFILE_TYPE_ENTRY pEntry;
+ OPENASINFO Info;
+ NEWEXT_DIALOG newext;
+ EDITTYPE_DIALOG edittype;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ pEntry = FileTypesDlg_DoList(hwndDlg);
+
+ // Disable the Delete button if the listview is empty
+ // the selected item should not be deleted by the user
+ if (pEntry == NULL || (pEntry->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, NewExtDlgProc,
(LPARAM)&newext))
+ {
+ FileTypesDlg_AddExt(hwndDlg, newext.szExt, newext.szFileType);
+ }
+ break;
+
+ case IDC_FILETYPES_DELETE:
+ FileTypesDlg_OnDelete(hwndDlg);
+ break;
+
+ case IDC_FILETYPES_CHANGE:
+ pEntry = FileTypesDlg_GetEntry(GetDlgItem(hwndDlg,
IDC_FILETYPES_LISTVIEW));
+ if (pEntry)
+ {
+ Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT;
+ Info.pcszClass = pEntry->FileExtension;
+ SHOpenWithDialog(hwndDlg, &Info);
+ }
+ break;
+
+ case IDC_FILETYPES_ADVANCED:
+ edittype.hwndLV = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
+ edittype.pEntry = FileTypesDlg_GetEntry(edittype.hwndLV);
+ DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_EDITTYPE),
+ hwndDlg, EditTypeDlgProc, (LPARAM)&edittype);
+ break;
+ }
+ break;
+
+ case WM_NOTIFY:
+ lppl = (LPNMLISTVIEW) lParam;
+ switch (lppl->hdr.code)
+ {
+ case LVN_KEYDOWN:
+ {
+ LV_KEYDOWN *pKeyDown = (LV_KEYDOWN *)lParam;
+ if (pKeyDown->wVKey == VK_DELETE)
+ {
+ FileTypesDlg_OnDelete(hwndDlg);
+ }
+ break;
+ }
+
+ case NM_DBLCLK:
+ edittype.hwndLV = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
+ edittype.pEntry = FileTypesDlg_GetEntry(edittype.hwndLV);
+ DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_EDITTYPE),
+ hwndDlg, EditTypeDlgProc, (LPARAM)&edittype);
+ break;
+
+ case LVN_DELETEALLITEMS:
+ return FALSE; // send LVN_DELETEITEM
+
+ case LVN_DELETEITEM:
+ pEntry = FileTypesDlg_GetEntry(lppl->hdr.hwndFrom,
lppl->iItem);
+ if (pEntry)
+ {
+ DestroyIcon(pEntry->hIconLarge);
+ DestroyIcon(pEntry->hIconSmall);
+ HeapFree(GetProcessHeap(), 0, pEntry);
+ }
+ return FALSE;
+
+ case LVN_ITEMCHANGING:
+ pEntry = FileTypesDlg_GetEntry(lppl->hdr.hwndFrom,
lppl->iItem);
+ if (!pEntry)
+ {
+ return TRUE;
+ }
+
+ if (!(lppl->uOldState & LVIS_FOCUSED) &&
(lppl->uNewState & LVIS_FOCUSED))
+ {
+ FileTypesDlg_OnItemChanging(hwndDlg, pEntry);
+ }
+ break;
+
+ case PSN_SETACTIVE:
+ // On page activation, set the focus to the listview
+ SetFocus(GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW));
+ break;
+ }
+ break;
+ }
+
+ return FALSE;
+}
diff --git a/dll/win32/shell32/dialogs/folder_options.cpp
b/dll/win32/shell32/dialogs/folder_options.cpp
index 0675eacf67..1fb4e7344f 100644
--- a/dll/win32/shell32/dialogs/folder_options.cpp
+++ b/dll/win32/shell32/dialogs/folder_options.cpp
@@ -1,5 +1,5 @@
/*
- * Open With Context Menu extension
+ * Folder Options
*
* Copyright 2007 Johannes Anderwald <johannes.anderwald(a)reactos.org>
* Copyright 2016-2018 Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
@@ -23,148 +23,22 @@
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];
- WCHAR ClassName[64];
- DWORD EditFlags;
- WCHAR AppName[64];
- HICON hIconLarge;
- HICON hIconSmall;
- WCHAR ProgramPath[MAX_PATH];
- WCHAR IconPath[MAX_PATH];
- INT nIconIndex;
-} 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;
@@ -181,7 +55,7 @@ Create24BppBitmap(HDC hDC, INT cx, INT cy)
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)
@@ -209,8 +83,7 @@ static HBITMAP BitmapFromIcon(HICON hIcon, INT cx, INT cy)
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);
@@ -238,8 +111,7 @@ CreateCheckImage(HDC hDC, BOOL bCheck, BOOL bEnabled = TRUE)
return hbm; // success
}
-static HBITMAP
-CreateCheckMask(HDC hDC)
+HBITMAP CreateCheckMask(HDC hDC)
{
INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
@@ -263,8 +135,7 @@ CreateCheckMask(HDC hDC)
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);
@@ -292,8 +163,7 @@ CreateRadioImage(HDC hDC, BOOL bCheck, BOOL bEnabled = TRUE)
return hbm; // success
}
-static HBITMAP
-CreateRadioMask(HDC hDC)
+HBITMAP CreateRadioMask(HDC hDC)
{
INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON);
INT cySmallIcon = GetSystemMetrics(SM_CYSMICON);
@@ -318,2755 +188,46 @@ CreateRadioMask(HDC hDC)
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 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(
- HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- 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 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)
+ShowFolderOptionsDialog(HWND hWnd, HINSTANCE hInst)
{
- 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
+ PROPSHEETHEADERW pinfo;
+ HPROPSHEETPAGE hppages[3];
+ HPROPSHEETPAGE hpage;
+ UINT num_pages = 0;
+ WCHAR szOptions[100];
- ADVANCED_ENTRY *pEntry = Advanced_GetItem(Item.lParam);
- if (pEntry == NULL)
- return FALSE; // no such item
- if (pEntry->bGrayed)
- return FALSE; // disabled
+ hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL,
FolderOptionsGeneralDlg, 0, NULL);
+ if (hpage)
+ hppages[num_pages++] = hpage;
- // toggle check mark
- Item.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
- switch (pEntry->dwType)
- {
- case AETYPE_CHECKBOX:
- pEntry->bChecked = !pEntry->bChecked;
- break;
+ hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW, FolderOptionsViewDlg, 0,
NULL);
+ if (hpage)
+ hppages[num_pages++] = hpage;
- 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;
+ hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES,
FolderOptionsFileTypesDlg, 0, NULL);
+ if (hpage)
+ hppages[num_pages++] = hpage;
- Item.hItem = pEntry2->hItem;
- INT iImage = Advanced_GetImage(pEntry2);
- Item.iImage = Item.iSelectedImage = iImage;
- TreeView_SetItem(hwndTreeView, &Item);
- }
- }
- pEntry->bChecked = TRUE;
- break;
+ szOptions[0] = 0;
+ LoadStringW(shell32_hInstance, IDS_FOLDER_OPTIONS, szOptions, _countof(szOptions));
+ szOptions[_countof(szOptions) - 1] = 0;
- default:
- return FALSE; // failure
- }
- Item.iImage = Item.iSelectedImage = Advanced_GetImage(pEntry);
- Item.hItem = hItem;
- TreeView_SetItem(hwndTreeView, &Item);
+ memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW));
+ pinfo.dwSize = sizeof(PROPSHEETHEADERW);
+ pinfo.dwFlags = PSH_NOCONTEXTHELP;
+ pinfo.nPages = num_pages;
+ pinfo.phpage = hppages;
+ pinfo.pszCaption = szOptions;
- // redraw the item
- RECT rcItem;
- TreeView_GetItemRect(hwndTreeView, hItem, &rcItem, FALSE);
- InvalidateRect(hwndTreeView, &rcItem, TRUE);
- return TRUE; // success
+ PropertySheetW(&pinfo);
}
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)
-{
- 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)
-{
- 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;
- }
-
- Entry->nIconIndex = PathParseIconLocationW(szLocation);
- StringCchCopyW(Entry->IconPath, _countof(Entry->IconPath), szLocation);
- Entry->hIconLarge = DoExtractIcon(Entry, szLocation, Entry->nIconIndex,
FALSE);
- Entry->hIconSmall = DoExtractIcon(Entry, szLocation, Entry->nIconIndex, 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));
- StringCchCopyW(Entry->IconPath, _countof(Entry->IconPath),
L"%SystemRoot%\\system32\\shell32.dll");
- Entry->nIconIndex = -IDI_SHELL_EXE;
- }
- 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 void
-SetFileTypeEntryDefaultIcon(PFOLDER_FILE_TYPE_ENTRY Entry)
-{
- 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));
- StringCchCopyW(Entry->IconPath, _countof(Entry->IconPath),
L"%SystemRoot%\\system32\\shell32.dll");
- Entry->nIconIndex = -IDI_SHELL_FOLDER_OPTIONS;
-}
-
-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;
- }
-
- Entry->ClassName[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)
- {
- DWORD dwSize = sizeof(Entry->ClassName);
- RegQueryValueExW(hTemp, NULL, NULL, NULL, LPBYTE(Entry->ClassName),
&dwSize);
-
- /* 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
- SetFileTypeEntryDefaultIcon(Entry);
- }
-
- /* 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 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->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 LPCWSTR s_pszSpace = L" \t\n\r\f\v";
-
-static BOOL
-NewExtDlg_OnOK(HWND hwndDlg, NEWEXT_DIALOG *pNewExt)
-{
- LV_FINDINFO find;
- INT iItem;
-
- GetDlgItemTextW(hwndDlg, IDC_NEWEXT_EDIT, pNewExt->szExt,
_countof(pNewExt->szExt));
- StrTrimW(pNewExt->szExt, s_pszSpace);
- CharUpperW(pNewExt->szExt);
-
- GetDlgItemTextW(hwndDlg, IDC_NEWEXT_COMBOBOX, pNewExt->szFileType,
_countof(pNewExt->szFileType));
- StrTrimW(pNewExt->szFileType, s_pszSpace);
-
- 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);
-}
-
-struct EDITTYPE_DIALOG
-{
- HWND hwndLV;
- FOLDER_FILE_TYPE_ENTRY *pEntry;
- CSimpleMap<CStringW, CStringW> CommandLineMap;
- WCHAR szIconPath[MAX_PATH];
- INT nIconIndex;
- WCHAR szDefaultVerb[64];
-};
-
-static BOOL
-EditTypeDlg_ReadClass(HWND hwndDlg, EDITTYPE_DIALOG *pEditType, LPCWSTR ClassKey)
-{
- // open class key
- HKEY hClassKey;
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, ClassKey, 0, KEY_READ, &hClassKey) !=
ERROR_SUCCESS)
- return FALSE;
-
- // open "shell" key
- HKEY hShellKey;
- if (RegOpenKeyExW(hClassKey, L"shell", 0, KEY_READ, &hShellKey) !=
ERROR_SUCCESS)
- {
- RegCloseKey(hClassKey);
- return FALSE;
- }
-
- WCHAR DefaultVerb[64];
- DWORD dwSize = sizeof(DefaultVerb);
- if (RegQueryValueExW(hShellKey, NULL, NULL, NULL, LPBYTE(DefaultVerb), &dwSize)
== ERROR_SUCCESS)
- {
- StringCchCopyW(pEditType->szDefaultVerb,
_countof(pEditType->szDefaultVerb), DefaultVerb);
- }
- else
- {
- StringCchCopyW(pEditType->szDefaultVerb,
_countof(pEditType->szDefaultVerb), L"open");
- }
-
- // enumerate shell verbs
- WCHAR szVerbName[64];
- DWORD dwIndex = 0;
- while (RegEnumKeyW(hShellKey, dwIndex, szVerbName, _countof(szVerbName)) ==
ERROR_SUCCESS)
- {
- // open verb key
- HKEY hVerbKey;
- LONG nResult = RegOpenKeyExW(hShellKey, szVerbName, 0, KEY_READ, &hVerbKey);
- if (nResult == ERROR_SUCCESS)
- {
- // open command key
- HKEY hCommandKey;
- nResult = RegOpenKeyExW(hVerbKey, L"command", 0, KEY_READ,
&hCommandKey);
- if (nResult == ERROR_SUCCESS)
- {
- // get command line
- WCHAR szValue[MAX_PATH + 32];
- dwSize = sizeof(szValue);
- nResult = RegQueryValueExW(hCommandKey, NULL, NULL, NULL,
LPBYTE(szValue), &dwSize);
- if (nResult == ERROR_SUCCESS)
- {
- pEditType->CommandLineMap.SetAt(szVerbName, szValue);
- }
-
- RegCloseKey(hCommandKey);
- }
-
- RegCloseKey(hVerbKey);
- }
- SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_ADDSTRING, 0,
LPARAM(szVerbName));
- ++dwIndex;
- }
-
- RegCloseKey(hShellKey);
- RegCloseKey(hClassKey);
-
- return TRUE;
-}
-
-static BOOL
-EditTypeDlg_WriteClass(HWND hwndDlg, EDITTYPE_DIALOG *pEditType,
- LPCWSTR ClassKey, LPCWSTR ClassName, INT cchName)
-{
- FOLDER_FILE_TYPE_ENTRY *pEntry = pEditType->pEntry;
-
- if (ClassKey[0] == 0)
- return FALSE;
-
- // create or open class key
- HKEY hClassKey;
- if (RegCreateKeyExW(HKEY_CLASSES_ROOT, ClassKey, 0, NULL, 0, KEY_WRITE, NULL,
&hClassKey, NULL) != ERROR_SUCCESS)
- return FALSE;
-
- // create "DefaultIcon" key
- if (pEntry->IconPath[0])
- {
- HKEY hDefaultIconKey;
- if (RegCreateKeyExW(hClassKey, L"DefaultIcon", 0, NULL, 0, KEY_WRITE,
NULL, &hDefaultIconKey, NULL) == ERROR_SUCCESS)
- {
- WCHAR szText[MAX_PATH];
- StringCchPrintfW(szText, _countof(szText), L"%s,%d",
pEntry->IconPath, pEntry->nIconIndex);
-
- // set icon location
- DWORD dwSize = (lstrlenW(szText) + 1) * sizeof(WCHAR);
- RegSetValueExW(hDefaultIconKey, NULL, 0, REG_EXPAND_SZ, LPBYTE(szText),
dwSize);
-
- RegCloseKey(hDefaultIconKey);
- }
- }
-
- // create "shell" key
- HKEY hShellKey;
- if (RegCreateKeyExW(hClassKey, L"shell", 0, NULL, 0, KEY_WRITE, NULL,
&hShellKey, NULL) != ERROR_SUCCESS)
- {
- RegCloseKey(hClassKey);
- return FALSE;
- }
-
- // delete shell commands
- WCHAR szVerbName[64];
- DWORD dwIndex = 0;
- while (RegEnumKeyW(hShellKey, dwIndex, szVerbName, _countof(szVerbName)) ==
ERROR_SUCCESS)
- {
- if (pEditType->CommandLineMap.FindKey(szVerbName) == -1)
- {
- // doesn't exist in CommandLineMap, then delete it
- if (SHDeleteKeyW(hShellKey, szVerbName) == ERROR_SUCCESS)
- {
- --dwIndex;
- }
- }
- ++dwIndex;
- }
-
- // set default action
- RegSetValueExW(hShellKey, NULL, 0, REG_SZ, LPBYTE(pEditType->szDefaultVerb),
sizeof(pEditType->szDefaultVerb));
-
- // write shell commands
- const INT nCount = pEditType->CommandLineMap.GetSize();
- for (INT i = 0; i < nCount; ++i)
- {
- CStringW& key = pEditType->CommandLineMap.GetKeyAt(i);
- CStringW& value = pEditType->CommandLineMap.GetValueAt(i);
-
- // create verb key
- HKEY hVerbKey;
- if (RegCreateKeyExW(hShellKey, key, 0, NULL, 0, KEY_WRITE, NULL, &hVerbKey,
NULL) == ERROR_SUCCESS)
- {
- // create command key
- HKEY hCommandKey;
- if (RegCreateKeyExW(hVerbKey, L"command", 0, NULL, 0, KEY_WRITE,
NULL, &hCommandKey, NULL) == ERROR_SUCCESS)
- {
- // write the default value
- DWORD dwSize = (value.GetLength() + 1) * sizeof(WCHAR);
- RegSetValueExW(hCommandKey, NULL, 0, REG_EXPAND_SZ,
LPBYTE(LPCWSTR(value)), dwSize);
-
- RegCloseKey(hCommandKey);
- }
-
- RegCloseKey(hVerbKey);
- }
- }
-
- // set class name to class key
- RegSetValueExW(hClassKey, NULL, 0, REG_SZ, LPBYTE(ClassName), cchName);
-
- RegCloseKey(hShellKey);
- RegCloseKey(hClassKey);
-
- return TRUE;
-}
-
-static BOOL
-EditTypeDlg_OnInitDialog(HWND hwndDlg, EDITTYPE_DIALOG *pEditType)
-{
- FOLDER_FILE_TYPE_ENTRY *pEntry = pEditType->pEntry;
- StringCchCopyW(pEditType->szIconPath, _countof(pEditType->szIconPath),
pEntry->IconPath);
- pEditType->nIconIndex = pEntry->nIconIndex;
- StringCchCopyW(pEditType->szDefaultVerb, _countof(pEditType->szDefaultVerb),
L"open");
-
- // set info
- SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_ICON, STM_SETICON,
(WPARAM)pEntry->hIconLarge, 0);
- SetDlgItemTextW(hwndDlg, IDC_EDITTYPE_TEXT, pEntry->ClassName);
- EditTypeDlg_ReadClass(hwndDlg, pEditType, pEntry->ClassKey);
- InvalidateRect(GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX), NULL, TRUE);
-
- // is listbox empty?
- if (SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_GETCOUNT, 0, 0) == 0)
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_EDIT_BUTTON), FALSE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_REMOVE), FALSE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SET_DEFAULT), FALSE);
- }
- else
- {
- // select first item
- SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_SETCURSEL, 0, 0);
- }
-
- EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SAME_WINDOW), FALSE);
-
- return TRUE;
-}
-
-static BOOL
-EditTypeDlg_OnRemove(HWND hwndDlg, EDITTYPE_DIALOG *pEditType)
-{
- // get current selection
- INT iItem = SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_GETCURSEL, 0, 0);
- if (iItem == LB_ERR)
- return FALSE;
-
- // ask user for removal
- CStringW strText(MAKEINTRESOURCEW(IDS_REMOVE_ACTION));
- CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
- if (MessageBoxW(hwndDlg, strText, strTitle, MB_ICONINFORMATION | MB_YESNO) == IDNO)
- return FALSE;
-
- // get text
- WCHAR szText[64];
- szText[0] = 0;
- SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_GETTEXT, iItem,
(LPARAM)szText);
- StrTrimW(szText, s_pszSpace);
-
- // remove it
- pEditType->CommandLineMap.Remove(szText);
- SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_DELETESTRING, iItem, 0);
- return TRUE;
-}
-
-static BOOL
-EditTypeDlg_UpdateEntryIcon(HWND hwndDlg, EDITTYPE_DIALOG *pEditType, LPCWSTR IconPath,
INT IconIndex)
-{
- FOLDER_FILE_TYPE_ENTRY *pEntry = pEditType->pEntry;
-
- BOOL bIconSet = FALSE;
- if (IconPath && IconPath[0])
- {
- DestroyIcon(pEntry->hIconLarge);
- DestroyIcon(pEntry->hIconSmall);
- pEntry->hIconLarge = DoExtractIcon(pEntry, IconPath, IconIndex, FALSE);
- pEntry->hIconSmall = DoExtractIcon(pEntry, IconPath, IconIndex, TRUE);
-
- bIconSet = (pEntry->hIconLarge && pEntry->hIconSmall);
- }
- if (bIconSet)
- {
- StringCchCopyW(pEntry->IconPath, _countof(pEntry->IconPath), IconPath);
- pEntry->nIconIndex = IconIndex;
- }
- else
- {
- SetFileTypeEntryDefaultIcon(pEntry);
- }
-
- HWND hListView = pEditType->hwndLV;
- HIMAGELIST himlLarge = ListView_GetImageList(hListView, LVSIL_NORMAL);
- HIMAGELIST himlSmall = ListView_GetImageList(hListView, LVSIL_SMALL);
-
- INT iLargeImage = ImageList_AddIcon(himlLarge, pEntry->hIconLarge);
- INT iSmallImage = ImageList_AddIcon(himlSmall, pEntry->hIconSmall);
- ASSERT(iLargeImage == iSmallImage);
-
- INT iItem = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
- if (iItem != -1)
- {
- LV_ITEMW Item = { LVIF_IMAGE, iItem };
- Item.iImage = iSmallImage;
- ListView_SetItem(hListView, &Item);
- }
- return TRUE;
-}
-
-static void
-EditTypeDlg_OnOK(HWND hwndDlg, EDITTYPE_DIALOG *pEditType)
-{
- FOLDER_FILE_TYPE_ENTRY *pEntry = pEditType->pEntry;
-
- // get class name
- GetDlgItemTextW(hwndDlg, IDC_EDITTYPE_TEXT, pEntry->ClassName,
_countof(pEntry->ClassName));
- StrTrimW(pEntry->ClassName, s_pszSpace);
-
- // update entry icon
- EditTypeDlg_UpdateEntryIcon(hwndDlg, pEditType, pEditType->szIconPath,
pEditType->nIconIndex);
-
- // write registry
- EditTypeDlg_WriteClass(hwndDlg, pEditType, pEntry->ClassKey, pEntry->ClassName,
_countof(pEntry->ClassName));
-
- // update the icon cache
- SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, NULL, NULL);
-
- EndDialog(hwndDlg, IDOK);
-}
-
-struct ACTION_DIALOG
-{
- HWND hwndLB;
- WCHAR ClassName[64];
- WCHAR szAction[64];
- WCHAR szApp[MAX_PATH];
- BOOL bUseDDE;
-};
-
-static void
-NewAct_OnOK(HWND hwndDlg, ACTION_DIALOG *pNewAct)
-{
- GetDlgItemTextW(hwndDlg, IDC_ACTION_ACTION, pNewAct->szAction,
_countof(pNewAct->szAction));
- GetDlgItemTextW(hwndDlg, IDC_ACTION_APP, pNewAct->szApp,
_countof(pNewAct->szApp));
- StrTrimW(pNewAct->szAction, s_pszSpace);
- StrTrimW(pNewAct->szApp, s_pszSpace);
- if (pNewAct->szAction[0] == 0)
- {
- // action is empty, error
- HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_ACTION);
- SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
- SetFocus(hwndCtrl);
- CStringW strText(MAKEINTRESOURCEW(IDS_SPECIFY_ACTION));
- CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
- MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
- return;
- }
- if (pNewAct->szApp[0] == 0 || GetFileAttributesW(pNewAct->szApp) ==
0xFFFFFFFF)
- {
- // app is invalid
- HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_APP);
- SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
- SetFocus(hwndCtrl);
- CStringW strText(MAKEINTRESOURCEW(IDS_INVALID_PROGRAM));
- CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
- MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
- return;
- }
- EndDialog(hwndDlg, IDOK);
-}
-
-static void
-Action_OnBrowse(HWND hwndDlg, ACTION_DIALOG *pNewAct, BOOL bEdit = FALSE)
-{
- WCHAR szFile[MAX_PATH];
- szFile[0] = 0;
-
- WCHAR szFilter[MAX_PATH];
- LoadStringW(shell32_hInstance, IDS_EXE_FILTER, szFilter, _countof(szFilter));
-
- CStringW strTitle(MAKEINTRESOURCEW(IDS_OPEN_WITH));
-
- OPENFILENAMEW ofn;
- ZeroMemory(&ofn, sizeof(ofn));
- ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
- ofn.hwndOwner = hwndDlg;
- ofn.lpstrFilter = szFilter;
- ofn.lpstrFile = szFile;
- ofn.nMaxFile = _countof(szFile);
- ofn.lpstrTitle = strTitle;
- ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST |
OFN_HIDEREADONLY;
- ofn.lpstrDefExt = L"exe";
- if (GetOpenFileNameW(&ofn))
- {
- if (bEdit)
- {
- CStringW str = szFile;
- str += L" \"%1\"";
- SetDlgItemTextW(hwndDlg, IDC_ACTION_APP, str);
- }
- else
- {
- SetDlgItemTextW(hwndDlg, IDC_ACTION_APP, szFile);
- }
- }
-}
-
-INT_PTR CALLBACK
-NewActionDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- static ACTION_DIALOG *s_pNewAct = NULL;
-
- switch (uMsg)
- {
- case WM_INITDIALOG:
- s_pNewAct = (ACTION_DIALOG *)lParam;
- s_pNewAct->bUseDDE = FALSE;
- EnableWindow(GetDlgItem(hwndDlg, IDC_ACTION_USE_DDE), FALSE);
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK:
- NewAct_OnOK(hwndDlg, s_pNewAct);
- break;
-
- case IDCANCEL:
- EndDialog(hwndDlg, IDCANCEL);
- break;
-
- case IDC_ACTION_BROWSE:
- Action_OnBrowse(hwndDlg, s_pNewAct, FALSE);
- break;
- }
- break;
- }
- return 0;
-}
-
-static void
-EditAct_OnOK(HWND hwndDlg, ACTION_DIALOG *pEditAct)
-{
- GetDlgItemTextW(hwndDlg, IDC_ACTION_ACTION, pEditAct->szAction,
_countof(pEditAct->szAction));
- GetDlgItemTextW(hwndDlg, IDC_ACTION_APP, pEditAct->szApp,
_countof(pEditAct->szApp));
- StrTrimW(pEditAct->szAction, s_pszSpace);
- StrTrimW(pEditAct->szApp, s_pszSpace);
- if (pEditAct->szAction[0] == 0)
- {
- HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_ACTION);
- SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
- SetFocus(hwndCtrl);
- CStringW strText(MAKEINTRESOURCEW(IDS_SPECIFY_ACTION));
- CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
- MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
- }
- if (pEditAct->szApp[0] == 0)
- {
- HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_APP);
- SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
- SetFocus(hwndCtrl);
- CStringW strText(MAKEINTRESOURCEW(IDS_INVALID_PROGRAM));
- CStringW strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
- MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
- }
- EndDialog(hwndDlg, IDOK);
-}
-
-INT_PTR CALLBACK
-EditActionDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- static ACTION_DIALOG *s_pEditAct = NULL;
-
- switch (uMsg)
- {
- case WM_INITDIALOG:
- s_pEditAct = (ACTION_DIALOG *)lParam;
- s_pEditAct->bUseDDE = FALSE;
- SetDlgItemTextW(hwndDlg, IDC_ACTION_ACTION, s_pEditAct->szAction);
- SetDlgItemTextW(hwndDlg, IDC_ACTION_APP, s_pEditAct->szApp);
- EnableWindow(GetDlgItem(hwndDlg, IDC_ACTION_USE_DDE), FALSE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_ACTION_ACTION), FALSE);
- {
- // set title
- CStringW str(MAKEINTRESOURCEW(IDS_EDITING_ACTION));
- str += s_pEditAct->ClassName;
- SetWindowTextW(hwndDlg, str);
- }
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK:
- EditAct_OnOK(hwndDlg, s_pEditAct);
- break;
-
- case IDCANCEL:
- EndDialog(hwndDlg, IDCANCEL);
- break;
-
- case IDC_ACTION_BROWSE:
- Action_OnBrowse(hwndDlg, s_pEditAct, TRUE);
- break;
- }
- break;
- }
- return 0;
-}
-
-static void
-EditTypeDlg_OnChangeIcon(HWND hwndDlg, EDITTYPE_DIALOG *pEditType)
-{
- WCHAR szPath[MAX_PATH];
- INT IconIndex;
-
- ExpandEnvironmentStringsW(pEditType->szIconPath, szPath, _countof(szPath));
- IconIndex = pEditType->nIconIndex;
- if (PickIconDlg(hwndDlg, szPath, _countof(szPath), &IconIndex))
- {
- // replace Windows directory with "%SystemRoot%" (for portability)
- WCHAR szWinDir[MAX_PATH];
- GetWindowsDirectoryW(szWinDir, _countof(szWinDir));
- if (wcsstr(szPath, szWinDir) == 0)
- {
- CStringW str(L"%SystemRoot%");
- str += &szPath[wcslen(szWinDir)];
- StringCchCopyW(szPath, _countof(szPath), LPCWSTR(str));
- }
-
- // update FOLDER_FILE_TYPE_ENTRY
- FOLDER_FILE_TYPE_ENTRY *pEntry = pEditType->pEntry;
- DestroyIcon(pEntry->hIconLarge);
- DestroyIcon(pEntry->hIconSmall);
- pEntry->hIconLarge = DoExtractIcon(pEntry, szPath, IconIndex, FALSE);
- pEntry->hIconSmall = DoExtractIcon(pEntry, szPath, IconIndex, TRUE);
-
- // update EDITTYPE_DIALOG
- StringCchCopyW(pEditType->szIconPath, _countof(pEditType->szIconPath),
szPath);
- pEditType->nIconIndex = IconIndex;
-
- // set icon to dialog
- SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_ICON, STM_SETICON,
(WPARAM)pEntry->hIconLarge, 0);
- }
-}
-
-static BOOL
-EditTypeDlg_OnDrawItem(HWND hwndDlg, LPDRAWITEMSTRUCT pDraw, EDITTYPE_DIALOG *pEditType)
-{
- WCHAR szText[64];
- HFONT hFont, hFont2;
-
- if (!pDraw)
- return FALSE;
-
- // fill rect and set colors
- if (pDraw->itemState & ODS_SELECTED)
- {
- FillRect(pDraw->hDC, &pDraw->rcItem, HBRUSH(COLOR_HIGHLIGHT + 1));
- SetTextColor(pDraw->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
- SetBkColor(pDraw->hDC, GetSysColor(COLOR_HIGHLIGHT));
- }
- else
- {
- FillRect(pDraw->hDC, &pDraw->rcItem, HBRUSH(COLOR_WINDOW + 1));
- SetTextColor(pDraw->hDC, GetSysColor(COLOR_WINDOWTEXT));
- SetBkColor(pDraw->hDC, GetSysColor(COLOR_WINDOW));
- }
-
- // get listbox text
- SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_GETTEXT, pDraw->itemID,
(LPARAM)szText);
-
- // is it default?
- hFont = (HFONT)SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, WM_GETFONT, 0, 0);
- if (lstrcmpiW(pEditType->szDefaultVerb, szText) == 0)
- {
- // default. set bold
- LOGFONTW lf;
- GetObject(hFont, sizeof(lf), &lf);
- lf.lfWeight = FW_BOLD;
- hFont2 = CreateFontIndirectW(&lf);
- if (hFont2)
- {
- HGDIOBJ hFontOld = SelectObject(pDraw->hDC, hFont2);
- InflateRect(&pDraw->rcItem, -2, -2);
- DrawTextW(pDraw->hDC, szText, -1, &pDraw->rcItem, DT_LEFT |
DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
- InflateRect(&pDraw->rcItem, 2, 2);
- SelectObject(pDraw->hDC, hFontOld);
- DeleteObject(hFont2);
- }
- }
- else
- {
- // non-default
- InflateRect(&pDraw->rcItem, -2, -2);
- DrawTextW(pDraw->hDC, szText, -1, &pDraw->rcItem, DT_LEFT | DT_VCENTER
| DT_SINGLELINE | DT_NOPREFIX);
- InflateRect(&pDraw->rcItem, 2, 2);
- }
-
- // draw focus rect
- if (pDraw->itemState & ODS_FOCUS)
- {
- DrawFocusRect(pDraw->hDC, &pDraw->rcItem);
- }
- return TRUE;
-}
-
-static BOOL
-EditTypeDlg_OnMeasureItem(HWND hwndDlg, LPMEASUREITEMSTRUCT pMeasure, EDITTYPE_DIALOG
*pEditType)
-{
- if (!pMeasure)
- return FALSE;
-
- HWND hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
-
- RECT rc;
- GetClientRect(hwndLB, &rc);
-
- HDC hDC = GetDC(hwndLB);
- if (hDC)
- {
- TEXTMETRICW tm;
- GetTextMetricsW(hDC, &tm);
- pMeasure->itemWidth = rc.right - rc.left;
- pMeasure->itemHeight = tm.tmHeight + 4;
- ReleaseDC(hwndLB, hDC);
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-EditTypeDlg_OnCommand(HWND hwndDlg, UINT id, UINT code, EDITTYPE_DIALOG *pEditType)
-{
- INT iItem, iIndex;
- ACTION_DIALOG action;
- switch (id)
- {
- case IDOK:
- EditTypeDlg_OnOK(hwndDlg, pEditType);
- break;
-
- case IDCANCEL:
- EndDialog(hwndDlg, IDCANCEL);
- break;
-
- case IDC_EDITTYPE_CHANGE_ICON:
- EditTypeDlg_OnChangeIcon(hwndDlg, pEditType);
- break;
-
- case IDC_EDITTYPE_NEW:
- action.bUseDDE = FALSE;
- action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
- StringCchPrintfW(action.ClassName, _countof(action.ClassName),
pEditType->pEntry->ClassName);
- // open 'New Action' dialog
- if (IDOK == DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_ACTION),
hwndDlg,
- NewActionDlgProc, LPARAM(&action)))
- {
- if (SendMessageW(action.hwndLB, LB_FINDSTRING, -1,
(LPARAM)action.szAction) != LB_ERR)
- {
- // already exists, error
- HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_ACTION_ACTION);
- SendMessageW(hwndCtrl, EM_SETSEL, 0, -1);
- SetFocus(hwndCtrl);
-
- CStringW strText, strTitle(MAKEINTRESOURCEW(IDS_FILE_TYPES));
- strText.Format(IDS_ACTION_EXISTS, action.szAction);
- MessageBoxW(hwndDlg, strText, strTitle, MB_ICONERROR);
- }
- else
- {
- // add it
- CStringW strCommandLine = action.szApp;
- strCommandLine += L" \"%1\"";
- pEditType->CommandLineMap.SetAt(action.szAction, strCommandLine);
- SendMessageW(action.hwndLB, LB_ADDSTRING, 0,
LPARAM(action.szAction));
- if (SendMessageW(action.hwndLB, LB_GETCOUNT, 0, 0) == 1)
- {
- // set default
- StringCchCopyW(pEditType->szDefaultVerb,
_countof(pEditType->szDefaultVerb), action.szAction);
- InvalidateRect(action.hwndLB, NULL, TRUE);
- }
- }
- }
- break;
-
- case IDC_EDITTYPE_LISTBOX:
- if (code == LBN_SELCHANGE)
- {
- action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
- INT iItem = SendMessageW(action.hwndLB, LB_GETCURSEL, 0, 0);
- SendMessageW(action.hwndLB, LB_GETTEXT, iItem, LPARAM(action.szAction));
- if (lstrcmpiW(action.szAction, pEditType->szDefaultVerb) == 0)
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SET_DEFAULT), FALSE);
- }
- else
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SET_DEFAULT), TRUE);
- }
- break;
- }
- else if (code != LBN_DBLCLK)
- {
- break;
- }
- // FALL THROUGH
-
- case IDC_EDITTYPE_EDIT_BUTTON:
- action.bUseDDE = FALSE;
- action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
- StringCchPrintfW(action.ClassName, _countof(action.ClassName),
pEditType->pEntry->ClassName);
- iItem = SendMessageW(action.hwndLB, LB_GETCURSEL, 0, 0);
- if (iItem == LB_ERR)
- break;
-
- // get action
- SendMessageW(action.hwndLB, LB_GETTEXT, iItem, LPARAM(action.szAction));
-
- // get app
- {
- iIndex = pEditType->CommandLineMap.FindKey(action.szAction);
- CStringW str = pEditType->CommandLineMap.GetValueAt(iIndex);
- StringCchCopyW(action.szApp, _countof(action.szApp), LPCWSTR(str));
- }
-
- // open dialog
- if (IDOK == DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_ACTION),
hwndDlg,
- EditActionDlgProc, LPARAM(&action)))
- {
- SendMessageW(action.hwndLB, LB_DELETESTRING, iItem, 0);
- SendMessageW(action.hwndLB, LB_INSERTSTRING, iItem,
LPARAM(action.szAction));
- pEditType->CommandLineMap.SetAt(action.szAction, action.szApp);
- }
- break;
-
- case IDC_EDITTYPE_REMOVE:
- EditTypeDlg_OnRemove(hwndDlg, pEditType);
- break;
-
- case IDC_EDITTYPE_SET_DEFAULT:
- action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
- iItem = SendMessageW(action.hwndLB, LB_GETCURSEL, 0, 0);
- if (iItem == LB_ERR)
- break;
-
- SendMessageW(action.hwndLB, LB_GETTEXT, iItem, LPARAM(action.szAction));
-
- // set default
- StringCchCopyW(pEditType->szDefaultVerb,
_countof(pEditType->szDefaultVerb), action.szAction);
- EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SET_DEFAULT), FALSE);
- InvalidateRect(action.hwndLB, NULL, TRUE);
- break;
- }
-}
-
-INT_PTR CALLBACK
-EditTypeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- static EDITTYPE_DIALOG *s_pEditType = NULL;
- LPDRAWITEMSTRUCT pDraw;
- LPMEASUREITEMSTRUCT pMeasure;
-
- switch (uMsg)
- {
- case WM_INITDIALOG:
- s_pEditType = (EDITTYPE_DIALOG *)lParam;
- return EditTypeDlg_OnInitDialog(hwndDlg, s_pEditType);
-
- case WM_DRAWITEM:
- pDraw = LPDRAWITEMSTRUCT(lParam);
- return EditTypeDlg_OnDrawItem(hwndDlg, pDraw, s_pEditType);
-
- case WM_MEASUREITEM:
- pMeasure = LPMEASUREITEMSTRUCT(lParam);
- return EditTypeDlg_OnMeasureItem(hwndDlg, pMeasure, s_pEditType);
-
- case WM_COMMAND:
- EditTypeDlg_OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), s_pEditType);
- break;
- }
-
- return 0;
-}
-
-static void
-EditTypeDlg_OnDelete(HWND hwndDlg)
-{
- 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);
- }
-}
-
-// 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;
- EDITTYPE_DIALOG edittype;
-
- 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:
- EditTypeDlg_OnDelete(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;
-
- case IDC_FILETYPES_ADVANCED:
- edittype.hwndLV = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
- edittype.pEntry = GetListViewEntry(edittype.hwndLV);
- DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_EDITTYPE),
- hwndDlg, EditTypeDlgProc, (LPARAM)&edittype);
- break;
- }
- break;
-
- case WM_NOTIFY:
- lppl = (LPNMLISTVIEW) lParam;
- switch (lppl->hdr.code)
- {
- case LVN_KEYDOWN:
- {
- LV_KEYDOWN *pKeyDown = (LV_KEYDOWN *)lParam;
- if (pKeyDown->wVKey == VK_DELETE)
- {
- EditTypeDlg_OnDelete(hwndDlg);
- }
- break;
- }
-
- case NM_DBLCLK:
- edittype.hwndLV = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
- edittype.pEntry = GetListViewEntry(edittype.hwndLV);
- DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_EDITTYPE),
- hwndDlg, EditTypeDlgProc, (LPARAM)&edittype);
- break;
-
- 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)
@@ -3089,7 +250,8 @@ Options_RunDLLCommon(HWND hWnd, HINSTANCE hInst, int fOptions, DWORD
nCmdShow)
/*************************************************************************
* 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);
}
@@ -3097,7 +259,8 @@ EXTERN_C VOID WINAPI Options_RunDLL(HWND hWnd, HINSTANCE hInst,
LPCSTR cmd, DWOR
/*************************************************************************
* 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);
}
@@ -3105,7 +268,8 @@ EXTERN_C VOID WINAPI Options_RunDLLA(HWND hWnd, HINSTANCE hInst,
LPCSTR cmd, DWO
/*************************************************************************
* 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);
}
diff --git a/dll/win32/shell32/dialogs/folder_options.h
b/dll/win32/shell32/dialogs/folder_options.h
new file mode 100644
index 0000000000..7b5af73c14
--- /dev/null
+++ b/dll/win32/shell32/dialogs/folder_options.h
@@ -0,0 +1,55 @@
+/*
+ * Folder Options
+ *
+ * Copyright 2007 Johannes Anderwald <johannes.anderwald(a)reactos.org>
+ * Copyright 2016-2018 Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+// IDD_FOLDER_OPTIONS_GENERAL
+INT_PTR
+CALLBACK
+FolderOptionsGeneralDlg(
+ HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+
+// IDD_FOLDER_OPTIONS_VIEW
+INT_PTR CALLBACK
+FolderOptionsViewDlg(
+ HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+
+// IDD_FOLDER_OPTIONS_FILETYPES
+INT_PTR CALLBACK
+FolderOptionsFileTypesDlg(
+ HWND hwndDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+
+HBITMAP Create24BppBitmap(HDC hDC, INT cx, INT cy);
+HBITMAP BitmapFromIcon(HICON hIcon, INT cx, INT cy);
+HBITMAP CreateCheckImage(HDC hDC, BOOL bCheck, BOOL bEnabled = TRUE);
+HBITMAP CreateCheckMask(HDC hDC);
+HBITMAP CreateRadioImage(HDC hDC, BOOL bCheck, BOOL bEnabled = TRUE);
+HBITMAP CreateRadioMask(HDC hDC);
+
+extern LPCWSTR g_pszShell32;
+extern LPCWSTR g_pszSpace;
diff --git a/dll/win32/shell32/dialogs/general.cpp
b/dll/win32/shell32/dialogs/general.cpp
new file mode 100644
index 0000000000..e44f21cd82
--- /dev/null
+++ b/dll/win32/shell32/dialogs/general.cpp
@@ -0,0 +1,147 @@
+/*
+ * 'General' tab property sheet of Folder Options
+ *
+ * Copyright 2007 Johannes Anderwald <johannes.anderwald(a)reactos.org>
+ * Copyright 2016-2018 Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "precomp.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL (fprop);
+
+static VOID
+GeneralDlg_UpdateIcons(HWND hDlg)
+{
+ 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)
+ {
+ HWND hwndTaskIcon = GetDlgItem(hDlg, IDC_FOLDER_OPTIONS_TASKICON);
... 1788 lines suppressed ...