https://git.reactos.org/?p=reactos.git;a=commitdiff;h=43d07fe695d427c2f8099…
commit 43d07fe695d427c2f8099066d376d6b036db7d74
Author: Whindmar Saksit <whindsaks(a)proton.me>
AuthorDate: Mon Oct 14 18:03:28 2024 +0200
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Oct 14 18:03:28 2024 +0200
[SHELL32] File Types dialog: Add functionality, optimize loading time (#6122)
- Support loading protocols like XP
- Support most of the relevant EditFlags
- Support reading/writing the AlwaysShowExt and BrowserFlags properties
- Loads the list much faster with optimized code and delaying the large icon and
description string
- Reduce the number of magic buffer sizes by replacing them with defines that are in
the ballpark of being correct
- Implemented column sorting
- Removed custom icon extraction code
- Removed IDS_FILE_EXT_TYPE string because it must be the same as IDS_ANY_FILE
- Don't touch verb keys that are not edited to retain the original REG type
- Don't clobber unchanged %1 icon location when editing a type
CORE-19756
---
dll/win32/shell32/CDefaultContextMenu.cpp | 5 -
dll/win32/shell32/dialogs/filetypes.cpp | 1267 +++++++++++++++++------------
dll/win32/shell32/lang/bg-BG.rc | 4 -
dll/win32/shell32/lang/ca-ES.rc | 6 +-
dll/win32/shell32/lang/cs-CZ.rc | 4 -
dll/win32/shell32/lang/da-DK.rc | 6 +-
dll/win32/shell32/lang/de-DE.rc | 4 -
dll/win32/shell32/lang/el-GR.rc | 6 +-
dll/win32/shell32/lang/en-GB.rc | 6 +-
dll/win32/shell32/lang/en-US.rc | 6 +-
dll/win32/shell32/lang/es-ES.rc | 4 -
dll/win32/shell32/lang/et-EE.rc | 4 -
dll/win32/shell32/lang/eu-ES.rc | 4 -
dll/win32/shell32/lang/fi-FI.rc | 6 +-
dll/win32/shell32/lang/fr-FR.rc | 4 -
dll/win32/shell32/lang/he-IL.rc | 4 -
dll/win32/shell32/lang/hi-IN.rc | 4 -
dll/win32/shell32/lang/hu-HU.rc | 4 -
dll/win32/shell32/lang/id-ID.rc | 4 -
dll/win32/shell32/lang/it-IT.rc | 4 -
dll/win32/shell32/lang/ja-JP.rc | 4 -
dll/win32/shell32/lang/ko-KR.rc | 6 +-
dll/win32/shell32/lang/nl-NL.rc | 6 +-
dll/win32/shell32/lang/no-NO.rc | 6 +-
dll/win32/shell32/lang/pl-PL.rc | 4 -
dll/win32/shell32/lang/pt-BR.rc | 4 -
dll/win32/shell32/lang/pt-PT.rc | 4 -
dll/win32/shell32/lang/ro-RO.rc | 5 +-
dll/win32/shell32/lang/ru-RU.rc | 4 -
dll/win32/shell32/lang/sk-SK.rc | 6 +-
dll/win32/shell32/lang/sl-SI.rc | 6 +-
dll/win32/shell32/lang/sq-AL.rc | 4 -
dll/win32/shell32/lang/sv-SE.rc | 6 +-
dll/win32/shell32/lang/tr-TR.rc | 4 -
dll/win32/shell32/lang/uk-UA.rc | 4 -
dll/win32/shell32/lang/zh-CN.rc | 4 -
dll/win32/shell32/lang/zh-HK.rc | 4 -
dll/win32/shell32/lang/zh-TW.rc | 4 -
dll/win32/shell32/precomp.h | 1 +
dll/win32/shell32/shresdef.h | 1 -
dll/win32/shell32/utils.h | 47 ++
sdk/include/psdk/shlwapi.h | 26 +
42 files changed, 820 insertions(+), 696 deletions(-)
diff --git a/dll/win32/shell32/CDefaultContextMenu.cpp
b/dll/win32/shell32/CDefaultContextMenu.cpp
index 9bc9c97ab68..93d6ebe3bd4 100644
--- a/dll/win32/shell32/CDefaultContextMenu.cpp
+++ b/dll/win32/shell32/CDefaultContextMenu.cpp
@@ -23,11 +23,6 @@ SHELL_GetRegCLSID(HKEY hKey, LPCWSTR SubKey, LPCWSTR Value, CLSID
&clsid)
return !err ? CLSIDFromString(buf, &clsid) : HRESULT_FROM_WIN32(err);
}
-static inline bool RegValueExists(HKEY hKey, LPCWSTR Name)
-{
- return RegQueryValueExW(hKey, Name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
-}
-
static BOOL InsertMenuItemAt(HMENU hMenu, UINT Pos, UINT Flags)
{
MENUITEMINFOW mii;
diff --git a/dll/win32/shell32/dialogs/filetypes.cpp
b/dll/win32/shell32/dialogs/filetypes.cpp
index 47bdd00179f..33a7a1376bc 100644
--- a/dll/win32/shell32/dialogs/filetypes.cpp
+++ b/dll/win32/shell32/dialogs/filetypes.cpp
@@ -20,30 +20,128 @@
*/
#include "precomp.h"
+#include <atlpath.h>
WINE_DEFAULT_DEBUG_CHANNEL (fprop);
-// DefaultIcon = %SystemRoot%\system32\SHELL32.dll,-210
-// Verbs: Open / RunAs
-// Cmd: rundll32.exe shell32.dll,Options_RunDLL 0
+// rundll32.exe shell32.dll,Options_RunDLL 0
/////////////////////////////////////////////////////////////////////////////
-typedef struct FILE_TYPE_ENTRY
+#define FTA_MODIFYMASK (FTA_OpenIsSafe) // Bits modified by EditTypeDlg
+#define NOASSOCRESID IDI_SHELL_DOCUMENT
+#define SUPPORT_EXTENSIONWITHOUTPROGID 1 // NT5 does not support these but NT6 does
+
+#define ASSOC_CCHMAX (32 + 1) // Extension or protocol (INTERNET_MAX_SCHEME_LENGTH)
+#define TYPENAME_CCHMAX max(100, RTL_FIELD_SIZE(SHFILEINFOA, szTypeName))
+#define ICONLOCATION_CCHMAX (MAX_PATH + 1 + 11)
+
+typedef struct _FILE_TYPE_ENTRY
{
- WCHAR FileExtension[30];
- WCHAR FileDescription[100];
+ WCHAR FileExtension[ASSOC_CCHMAX];
+ WCHAR FileDescription[TYPENAME_CCHMAX];
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;
+
+ bool IsExtension() const
+ {
+ return FileExtension[0] == '.';
+ }
+ LPCWSTR GetAssocForDisplay() const
+ {
+ return FileExtension + (FileExtension[0] == '.');
+ }
+ void InvalidateTypeName()
+ {
+ FileDescription[0] = FileDescription[1] = UNICODE_NULL;
+ }
+ void InvalidateDefaultApp()
+ {
+ ProgramPath[0] = ProgramPath[1] = AppName[0] = AppName[1] = UNICODE_NULL;
+ }
+ void Initialize()
+ {
+ ClassKey[0] = UNICODE_NULL;
+ IconPath[0] = UNICODE_NULL;
+ nIconIndex = 0;
+ InvalidateTypeName();
+ InvalidateDefaultApp();
+ }
+ void DestroyIcons()
+ {
+ if (hIconSmall)
+ DestroyIcon(hIconSmall);
+ hIconSmall = NULL;
+ }
} FILE_TYPE_ENTRY, *PFILE_TYPE_ENTRY;
+typedef struct _FILE_TYPE_GLOBALS
+{
+ HIMAGELIST himlSmall;
+ UINT IconSize;
+ HICON hDefExtIconSmall;
+ HBITMAP hOpenWithImage;
+ HANDLE hHeap;
+ WCHAR DefExtTypeNameFmt[TYPENAME_CCHMAX];
+ WCHAR NoneString[42];
+ INT8 SortCol, SortReverse;
+ UINT Restricted;
+} FILE_TYPE_GLOBALS, *PFILE_TYPE_GLOBALS;
+
+static DWORD
+GetRegDWORD(HKEY hKey, LPCWSTR Name, DWORD &Value, DWORD DefaultValue = 0, BOOL
Strict = FALSE)
+{
+ DWORD cb = sizeof(DWORD), type;
+ LRESULT ec = RegQueryValueExW(hKey, Name, 0, &type, (BYTE*)&Value,
&cb);
+ if (ec == ERROR_SUCCESS)
+ {
+ if ((type == REG_DWORD && cb == sizeof(DWORD)) ||
+ (!Strict && type == REG_BINARY && (cb && cb <=
sizeof(DWORD))))
+ {
+ Value &= (0xffffffffUL >> (32 - cb * 8));
+ return ec;
+ }
+ }
+ Value = DefaultValue;
+ return ec ? ec : ERROR_BAD_FORMAT;
+}
+
+static DWORD
+GetRegDWORD(HKEY hKey, LPCWSTR Name, DWORD DefaultValue = 0)
+{
+ GetRegDWORD(hKey, Name, DefaultValue, DefaultValue, FALSE);
+ return DefaultValue;
+}
+
+static HRESULT
+GetClassKey(const FILE_TYPE_ENTRY &FTE, LPCWSTR &SubKey)
+{
+ HRESULT hr = S_OK;
+ LPCWSTR path = FTE.IsExtension() ? FTE.ClassKey : FTE.FileExtension;
+#if SUPPORT_EXTENSIONWITHOUTPROGID
+ if (!*path && FTE.IsExtension())
+ {
+ path = FTE.FileExtension;
+ hr = S_FALSE;
+ }
+#endif
+ ASSERT(*path);
+ SubKey = path;
+ return hr;
+}
+
+static void
+QuoteAppPathForCommand(CStringW &path)
+{
+ if (path.Find(' ') >= 0 && path.Find('\"') < 0)
+ path = CStringW(L"\"") + path + L"\"";
+}
+
static BOOL
DeleteExt(HWND hwndDlg, LPCWSTR pszExt)
{
@@ -56,14 +154,15 @@ DeleteExt(HWND hwndDlg, LPCWSTR pszExt)
return FALSE;
// query "extfile" key name
- WCHAR szValue[64] = { 0 };
- DWORD cbValue = sizeof(szValue);
- RegQueryValueExW(hKey, NULL, NULL, NULL, LPBYTE(szValue), &cbValue);
+ WCHAR ProgId[MAX_PATH] = { 0 };
+ DWORD cb = sizeof(ProgId);
+ RegQueryValueExW(hKey, NULL, NULL, NULL, LPBYTE(ProgId), &cb);
RegCloseKey(hKey);
+ // FIXME: Should verify that no other extensions are using this ProgId
// delete "extfile" key (if any)
- if (szValue[0])
- SHDeleteKeyW(HKEY_CLASSES_ROOT, szValue);
+ if (ProgId[0])
+ SHDeleteKeyW(HKEY_CLASSES_ROOT, ProgId);
// delete ".ext" key
BOOL ret = (SHDeleteKeyW(HKEY_CLASSES_ROOT, pszExt) == ERROR_SUCCESS);
@@ -75,133 +174,184 @@ DeleteExt(HWND hwndDlg, LPCWSTR pszExt)
}
static inline HICON
-DoExtractIcon(PFILE_TYPE_ENTRY Entry, LPCWSTR IconPath,
- INT iIndex = 0, BOOL bSmall = FALSE)
+DoExtractIcon(LPCWSTR IconPath, INT iIndex, UINT cx, UINT cy)
{
- 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;
+ return SHELL32_SHExtractIcon(IconPath, iIndex, cx, cy);
}
-static void
-DoFileTypeIconLocation(PFILE_TYPE_ENTRY Entry, LPCWSTR IconLocation)
+static HICON
+DoExtractIcon(LPCWSTR IconPath, INT iIndex = 0, BOOL bSmall = FALSE)
{
- // 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);
+ UINT cx = GetSystemMetrics(bSmall ? SM_CXSMICON : SM_CXICON);
+ UINT cy = GetSystemMetrics(bSmall ? SM_CYSMICON : SM_CYICON);
+ return DoExtractIcon(IconPath, iIndex, cx, cy);
}
static BOOL
-GetFileTypeIconsEx(PFILE_TYPE_ENTRY Entry, LPCWSTR IconLocation)
+GetFileTypeIconsEx(PFILE_TYPE_ENTRY Entry, LPCWSTR IconLocation, UINT IconSize)
{
- Entry->hIconLarge = Entry->hIconSmall = NULL;
-
- if (lstrcmpiW(Entry->FileExtension, L".exe") == 0 ||
- lstrcmpiW(Entry->FileExtension, L".scr") == 0)
+ Entry->hIconSmall = NULL;
+ if (lstrcmpW(IconLocation, L"%1") == 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
+ LPCWSTR ext = Entry->FileExtension;
+ if (!lstrcmpiW(ext, L".exe") || !lstrcmpiW(ext, L".scr"))
+ {
+ Entry->hIconSmall = HICON(LoadImageW(shell32_hInstance,
MAKEINTRESOURCEW(IDI_SHELL_EXE),
+ IMAGE_ICON, IconSize, IconSize, 0));
+ Entry->nIconIndex = -IDI_SHELL_EXE;
+ }
+ // Set the icon path to %1 on purpose so PickIconDlg will issue a warning
+ StringCbCopyW(Entry->IconPath, sizeof(Entry->IconPath), IconLocation);
}
else
{
- DoFileTypeIconLocation(Entry, IconLocation);
+ // Expand the REG_EXPAND_SZ string by environment variables
+ if (ExpandEnvironmentStringsW(IconLocation, Entry->IconPath,
_countof(Entry->IconPath)))
+ {
+ Entry->nIconIndex = PathParseIconLocationW(Entry->IconPath);
+ Entry->hIconSmall = DoExtractIcon(Entry->IconPath,
Entry->nIconIndex, IconSize, IconSize);
+ }
}
-
- return Entry->hIconLarge && Entry->hIconSmall;
+ return Entry->hIconSmall != NULL;
}
static BOOL
-GetFileTypeIconsByKey(HKEY hKey, PFILE_TYPE_ENTRY Entry)
+GetFileTypeIconsByKey(HKEY hKey, PFILE_TYPE_ENTRY Entry, UINT IconSize)
{
- Entry->hIconLarge = Entry->hIconSmall = NULL;
+ 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 };
+ WCHAR szLocation[ICONLOCATION_CCHMAX];
DWORD dwSize = sizeof(szLocation);
nResult = RegQueryValueExW(hDefIconKey, NULL, NULL, NULL, LPBYTE(szLocation),
&dwSize);
+ szLocation[_countof(szLocation) - 1] = UNICODE_NULL;
RegCloseKey(hDefIconKey);
-
- if (nResult != ERROR_SUCCESS || szLocation[0] == 0)
+ if (nResult != ERROR_SUCCESS || !szLocation[0])
return FALSE;
- return GetFileTypeIconsEx(Entry, szLocation);
+ return GetFileTypeIconsEx(Entry, szLocation, IconSize);
+}
+
+static LPCWSTR
+GetProgramPath(PFILE_TYPE_ENTRY Entry)
+{
+ if (!Entry->ProgramPath[1] && !Entry->ProgramPath[0])
+ {
+ DWORD cch = _countof(Entry->ProgramPath);
+ if (FAILED(AssocQueryStringW(ASSOCF_INIT_IGNOREUNKNOWN, ASSOCSTR_EXECUTABLE,
+ Entry->FileExtension, NULL,
Entry->ProgramPath, &cch)))
+ {
+ Entry->ProgramPath[0] = UNICODE_NULL;
+ Entry->ProgramPath[1] = TRUE;
+ }
+ }
+ return Entry->ProgramPath;
}
static BOOL
QueryFileDescription(LPCWSTR ProgramPath, LPWSTR pszName, INT cchName)
{
- SHFILEINFOW FileInfo = { 0 };
- if (SHGetFileInfoW(ProgramPath, 0, &FileInfo, sizeof(FileInfo),
SHGFI_DISPLAYNAME))
+ SHFILEINFOW fi;
+ fi.szDisplayName[0] = UNICODE_NULL;
+ if (SHGetFileInfoW(ProgramPath, 0, &fi, sizeof(fi), SHGFI_DISPLAYNAME))
{
- StringCchCopyW(pszName, cchName, FileInfo.szDisplayName);
+ StringCchCopyW(pszName, cchName, fi.szDisplayName);
return TRUE;
}
-
return !!GetFileTitleW(ProgramPath, pszName, cchName);
}
+static LPCWSTR
+GetAppName(PFILE_TYPE_ENTRY Entry)
+{
+ if (!Entry->AppName[1] && !Entry->AppName[0])
+ {
+ LPCWSTR exe = GetProgramPath(Entry);
+ if (!*exe || !QueryFileDescription(exe, Entry->AppName,
_countof(Entry->AppName)))
+ {
+ Entry->AppName[0] = UNICODE_NULL;
+ Entry->AppName[1] = TRUE;
+ }
+ }
+ return Entry->AppName;
+}
+
+static LPWSTR
+GetTypeName(PFILE_TYPE_ENTRY Entry, PFILE_TYPE_GLOBALS pG)
+{
+ if (!Entry->FileDescription[1] && !Entry->FileDescription[0])
+ {
+ Entry->FileDescription[1] = TRUE;
+ if (Entry->IsExtension())
+ {
+ SHFILEINFOW fi;
+ if (SHGetFileInfoW(Entry->FileExtension, 0, &fi, sizeof(fi),
SHGFI_TYPENAME |
+ SHGFI_USEFILEATTRIBUTES) && *fi.szTypeName)
+ {
+ StringCchCopyW(Entry->FileDescription,
_countof(Entry->FileDescription), fi.szTypeName);
+ }
+ else
+ {
+ // FIXME: Remove this hack when SHGetFileInfo is able to handle
extensions without a ProgId (.ASM etc)
+ StringCchPrintfW(Entry->FileDescription,
_countof(Entry->FileDescription),
+ pG->DefExtTypeNameFmt,
&Entry->FileExtension[1]);
+ }
+ }
+ else
+ {
+ // FIXME: Fix and use ASSOCSTR_FRIENDLYDOCNAME
+ DWORD cb = sizeof(Entry->FileDescription), Fallback = TRUE;
+ LPCWSTR ClassKey;
+ HRESULT hr = GetClassKey(*Entry, ClassKey);
+ HKEY hKey;
+ if (SUCCEEDED(hr) && !RegOpenKeyExW(HKEY_CLASSES_ROOT, ClassKey, 0,
KEY_READ, &hKey))
+ {
+ Fallback = RegQueryValueExW(hKey, NULL, 0, NULL,
(BYTE*)Entry->FileDescription, &cb) != ERROR_SUCCESS ||
+ !*Entry->FileDescription;
+ RegCloseKey(hKey);
+ }
+ if (Fallback)
+ {
+ StringCchCopyW(Entry->FileDescription,
_countof(Entry->FileDescription), Entry->FileExtension);
+ }
+ }
+ }
+ return Entry->FileDescription;
+}
+
static void
-SetFileTypeEntryDefaultIcon(PFILE_TYPE_ENTRY Entry)
+InitializeDefaultIcons(PFILE_TYPE_GLOBALS pG)
{
- 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;
+ const INT ResId = NOASSOCRESID;
+ if (!pG->hDefExtIconSmall)
+ {
+ pG->hDefExtIconSmall = HICON(LoadImageW(shell32_hInstance,
MAKEINTRESOURCEW(ResId),
+ IMAGE_ICON, pG->IconSize,
pG->IconSize, 0));
+ }
+
+ if (!ImageList_GetImageCount(pG->himlSmall))
+ {
+ int idx = ImageList_AddIcon(pG->himlSmall, pG->hDefExtIconSmall);
+ ASSERT(idx == 0);
+ }
+}
+
+static BOOL
+Normalize(PFILE_TYPE_ENTRY Entry)
+{
+ // We don't need this information until somebody tries to edit the entry
+ if (!Entry->IconPath[0])
+ {
+ StringCbCopyW(Entry->IconPath, sizeof(Entry->IconPath), g_pszShell32);
+ Entry->nIconIndex = NOASSOCRESID > 1 ? -NOASSOCRESID : 0;
+ }
+ return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
@@ -209,56 +359,56 @@ SetFileTypeEntryDefaultIcon(PFILE_TYPE_ENTRY Entry)
#define LISTBOX_MARGIN 2
+enum EDITTYPEFLAGS { ETF_ALWAYSEXT = 1 << 0, ETF_BROWSESAME = 1 << 1 };
+
typedef struct EDITTYPE_DIALOG
{
HWND hwndLV;
+ PFILE_TYPE_GLOBALS pG;
PFILE_TYPE_ENTRY pEntry;
CSimpleMap<CStringW, CStringW> CommandLineMap;
+ CAtlList<CStringW> ModifiedVerbs;
WCHAR szIconPath[MAX_PATH];
INT nIconIndex;
- WCHAR szDefaultVerb[64];
+ WCHAR szDefaultVerb[VERBKEY_CCHMAX];
+ WCHAR TypeName[TYPENAME_CCHMAX];
} EDITTYPE_DIALOG, *PEDITTYPE_DIALOG;
static void
EditTypeDlg_OnChangeIcon(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
{
WCHAR szPath[MAX_PATH];
- INT IconIndex;
-
+ INT IconIndex = pEditType->nIconIndex;
ExpandEnvironmentStringsW(pEditType->szIconPath, szPath, _countof(szPath));
- IconIndex = pEditType->nIconIndex;
if (PickIconDlg(hwndDlg, szPath, _countof(szPath), &IconIndex))
{
+ HICON hIconLarge = DoExtractIcon(szPath, IconIndex, FALSE);
+
// replace Windows directory with "%SystemRoot%" (for portability)
WCHAR szWinDir[MAX_PATH];
- GetWindowsDirectoryW(szWinDir, _countof(szWinDir));
- if (wcsstr(szPath, szWinDir) == 0)
+ UINT lenWinDir = GetWindowsDirectoryW(szWinDir, _countof(szWinDir));
+ if (StrStrIW(szPath, szWinDir) == szPath)
{
- CStringW str(L"%SystemRoot%");
- str += &szPath[wcslen(szWinDir)];
- StringCbCopyW(szPath, sizeof(szPath), LPCWSTR(str));
+ CPathW str(L"%SystemRoot%");
+ str.Append(&szPath[lenWinDir]);
+ StringCbCopyW(szPath, sizeof(szPath), 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);
+ HICON hOld = (HICON)SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_ICON, STM_SETICON,
(WPARAM)hIconLarge, 0);
+ if (hOld)
+ DestroyIcon(hOld);
}
}
static BOOL
EditTypeDlg_OnDrawItem(HWND hwndDlg, LPDRAWITEMSTRUCT pDraw, PEDITTYPE_DIALOG
pEditType)
{
- WCHAR szText[64];
+ WCHAR szText[MAX_PATH];
HFONT hFont, hFont2;
if (!pDraw)
@@ -367,6 +517,7 @@ NewExtDlg_OnAdvanced(HWND hwndDlg, PNEWEXT_DIALOG pNewExt)
GetWindowRect(GetDlgItem(hwndDlg, IDCANCEL), &rc2);
MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc2, 2);
+ HWND hClassCombo = GetDlgItem(hwndDlg, IDC_NEWEXT_COMBOBOX);
if (pNewExt->bAdvanced)
{
rc1.top += pNewExt->dy;
@@ -376,12 +527,12 @@ NewExtDlg_OnAdvanced(HWND hwndDlg, PNEWEXT_DIALOG pNewExt)
rc2.bottom += pNewExt->dy;
ShowWindow(GetDlgItem(hwndDlg, IDC_NEWEXT_ASSOC), SW_SHOWNOACTIVATE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_NEWEXT_COMBOBOX), SW_SHOWNOACTIVATE);
+ ShowWindow(hClassCombo, SW_SHOWNOACTIVATE);
CStringW strLeft(MAKEINTRESOURCEW(IDS_NEWEXT_ADVANCED_LEFT));
SetDlgItemTextW(hwndDlg, IDC_NEWEXT_ADVANCED, strLeft);
- SetFocus(GetDlgItem(hwndDlg, IDC_NEWEXT_COMBOBOX));
+ SetFocus(hClassCombo);
}
else
{
@@ -392,15 +543,14 @@ NewExtDlg_OnAdvanced(HWND hwndDlg, PNEWEXT_DIALOG pNewExt)
rc2.bottom -= pNewExt->dy;
ShowWindow(GetDlgItem(hwndDlg, IDC_NEWEXT_ASSOC), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_NEWEXT_COMBOBOX), SW_HIDE);
+ ShowWindow(hClassCombo, 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);
+ SendMessageW(hClassCombo, CB_SETCURSEL, 0, 0); // Reset the combo to the
"new class" mode
}
HDWP hDWP = BeginDeferWindowPos(3);
@@ -458,8 +608,12 @@ NewExtDlg_OnOK(HWND hwndDlg, PNEWEXT_DIALOG pNewExt)
StrTrimW(pNewExt->szExt, g_pszSpace);
_wcsupr(pNewExt->szExt);
+#if 0
+ // FIXME: Implement the "choose existing class" mode
GetDlgItemTextW(hwndDlg, IDC_NEWEXT_COMBOBOX, pNewExt->szFileType,
_countof(pNewExt->szFileType));
StrTrimW(pNewExt->szFileType, g_pszSpace);
+#endif
+ pNewExt->szFileType[0] = UNICODE_NULL; // "new class" mode
if (pNewExt->szExt[0] == 0)
{
@@ -486,7 +640,7 @@ NewExtDlg_OnOK(HWND hwndDlg, PNEWEXT_DIALOG pNewExt)
// already exists
// get file type
- WCHAR szFileType[64];
+ WCHAR szFileType[TYPENAME_CCHMAX];
LV_ITEM item;
ZeroMemory(&item, sizeof(item));
item.mask = LVIF_TEXT;
@@ -513,10 +667,8 @@ NewExtDlg_OnOK(HWND hwndDlg, PNEWEXT_DIALOG pNewExt)
CStringW strExt(L".");
strExt += find.psz;
strExt.MakeLower();
- DeleteExt(hwndDlg, strExt);
-
- // Delete the item
- ListView_DeleteItem(pNewExt->hwndLV, iItem);
+ if (DeleteExt(hwndDlg, strExt))
+ ListView_DeleteItem(pNewExt->hwndLV, iItem);
}
EndDialog(hwndDlg, IDOK);
@@ -561,192 +713,134 @@ NewExtDlgProc(
return 0;
}
-static BOOL
-FileTypesDlg_InsertToLV(HWND hListView, LPCWSTR szName, INT iItem, LPCWSTR szFile)
+static PFILE_TYPE_ENTRY
+FileTypesDlg_InsertToLV(HWND hListView, LPCWSTR Assoc, INT iItem, PFILE_TYPE_GLOBALS
pG)
{
PFILE_TYPE_ENTRY Entry;
- HKEY hKey;
+ HKEY hKey, hTemp;
LVITEMW lvItem;
DWORD dwSize;
- DWORD dwType;
- if (szName[0] != L'.')
+ if (RegOpenKeyExW(HKEY_CLASSES_ROOT, Assoc, 0, KEY_READ, &hKey) !=
ERROR_SUCCESS)
{
- // FIXME handle URL protocol handlers
- return FALSE;
+ return NULL;
}
-
- // 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)
+ if (Assoc[0] != L'.' && !RegValueExists(hKey, L"URL
Protocol"))
{
- HeapFree(GetProcessHeap(), 0, Entry);
- return FALSE;
+ RegCloseKey(hKey);
+ return NULL;
}
- // 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)
+ Entry = (PFILE_TYPE_ENTRY)HeapAlloc(pG->hHeap, 0, sizeof(FILE_TYPE_ENTRY));
+ if (!Entry)
{
- // no link available
- Entry->ClassKey[0] = 0;
+ RegCloseKey(hKey);
+ return NULL;
}
+ Entry->Initialize();
- Entry->ClassName[0] = 0;
- if (Entry->ClassKey[0])
+ if (Assoc[0] == L'.')
{
- HKEY hTemp;
- // try open linked key
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, Entry->ClassKey, 0, KEY_READ, &hTemp)
== ERROR_SUCCESS)
+ dwSize = sizeof(Entry->ClassKey);
+ if (RegQueryValueExW(hKey, NULL, NULL, NULL, LPBYTE(Entry->ClassKey),
&dwSize))
+ {
+ Entry->ClassKey[0] = UNICODE_NULL; // No ProgId
+ }
+#if SUPPORT_EXTENSIONWITHOUTPROGID
+ if (Entry->ClassKey[0] && !RegOpenKeyExW(HKEY_CLASSES_ROOT,
Entry->ClassKey, 0, KEY_READ, &hTemp))
{
- DWORD dwSize = sizeof(Entry->ClassName);
- RegQueryValueExW(hTemp, NULL, NULL, NULL, LPBYTE(Entry->ClassName),
&dwSize);
-
- // use linked key
RegCloseKey(hKey);
hKey = hTemp;
}
+#else
+ if (!Entry->ClassKey[0])
+ {
+ HeapFree(pG->hHeap, 0, Entry);
+ RegCloseKey(hKey);
+ return NULL;
+ }
+#endif
}
- // 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))
+ Entry->EditFlags = GetRegDWORD(hKey, L"EditFlags", 0);
+ if (Entry->EditFlags & FTA_Exclude)
{
- if ((dwType == REG_DWORD || dwType == REG_BINARY) && dwSize ==
sizeof(DWORD))
- RegQueryValueExW(hKey, L"EditFlags", NULL, NULL,
(LPBYTE)&Entry->EditFlags, &dwSize);
+ HeapFree(pG->hHeap, 0, Entry);
+ RegCloseKey(hKey);
+ return NULL;
}
- // convert extension to upper case
- wcscpy(Entry->FileExtension, szName);
- _wcsupr(Entry->FileExtension);
+ wcscpy(Entry->FileExtension, Assoc);
// get icon
- if (!GetFileTypeIconsByKey(hKey, Entry))
- {
- // set default icon
- SetFileTypeEntryDefaultIcon(Entry);
- }
+ Entry->IconPath[0] = UNICODE_NULL;
+ BOOL defaultIcon = !GetFileTypeIconsByKey(hKey, Entry, pG->IconSize);
- // 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)
+ INT iSmallImage = 0;
+ if (!defaultIcon && Entry->hIconSmall)
{
- iLargeImage = ImageList_AddIcon(himlLarge, Entry->hIconLarge);
- iSmallImage = ImageList_AddIcon(himlSmall, Entry->hIconSmall);
- ASSERT(iLargeImage == iSmallImage);
- DBG_UNREFERENCED_LOCAL_VARIABLE(iLargeImage);
+ iSmallImage = ImageList_AddIcon(pG->himlSmall, Entry->hIconSmall);
}
- // 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'
-
- StringCbPrintfW(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.iSubItem = 0;
lvItem.lParam = (LPARAM)Entry;
lvItem.iImage = iSmallImage;
+ lvItem.pszText = Assoc[0] == L'.' ? _wcsupr(&Entry->FileExtension[1])
: pG->NoneString;
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;
+ lvItem.pszText = LPSTR_TEXTCALLBACK;
ListView_SetItem(hListView, &lvItem);
- return TRUE;
+ return Entry;
}
static BOOL
-FileTypesDlg_AddExt(HWND hwndDlg, LPCWSTR pszExt, LPCWSTR pszFileType)
+FileTypesDlg_AddExt(HWND hwndDlg, LPCWSTR pszExt, LPCWSTR pszProgId, PFILE_TYPE_GLOBALS
pG)
{
DWORD dwValue = 1;
HKEY hKey;
WCHAR szKey[13]; // max. "ft4294967295" + "\0"
LONG nResult;
- // Search the next "ft%06u" key name
- do
+ if (!*pszProgId)
{
- StringCbPrintfW(szKey, sizeof(szKey), L"ft%06u", dwValue);
-
- nResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hKey);
- if (nResult != ERROR_SUCCESS)
- break;
+ pszProgId = szKey;
+ // Search the next "ft%06u" key name
+ do
+ {
+ StringCbPrintfW(szKey, sizeof(szKey), L"ft%06u", dwValue);
- RegCloseKey(hKey);
- ++dwValue;
- } while (dwValue != 0);
+ nResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hKey);
+ if (nResult != ERROR_SUCCESS)
+ break;
- RegCloseKey(hKey);
+ RegCloseKey(hKey);
+ ++dwValue;
+ } while (dwValue != 0);
- if (dwValue == 0)
- return FALSE;
+ RegCloseKey(hKey);
- // 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;
+ if (dwValue == 0)
+ return FALSE;
- RegCloseKey(hKey);
+ // 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'.')
+ WCHAR szExt[ASSOC_CCHMAX];
+ if (*pszExt == L'.') // The user is allowed to type the extension with or
without the . in the new dialog!
++pszExt;
StringCbPrintfW(szExt, sizeof(szExt), L".%s", pszExt);
_wcslwr(szExt);
@@ -756,37 +850,18 @@ FileTypesDlg_AddExt(HWND hwndDlg, LPCWSTR pszExt, LPCWSTR
pszFileType)
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);
+ RegSetString(hKey, NULL, pszProgId, REG_SZ);
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))
+ if (!FileTypesDlg_InsertToLV(hListView, szExt, iItem, pG))
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_SetItemState(hListView, iItem, -1, LVIS_FOCUSED | LVIS_SELECTED);
ListView_EnsureVisible(hListView, iItem, FALSE);
-
return TRUE;
}
@@ -799,13 +874,15 @@ FileTypesDlg_RemoveExt(HWND hwndDlg)
if (iItem == -1)
return FALSE;
- WCHAR szExt[20];
+ WCHAR szExt[MAX_PATH];
szExt[0] = L'.';
ListView_GetItemText(hListView, iItem, 0, &szExt[1], _countof(szExt) - 1);
_wcslwr(szExt);
- DeleteExt(hwndDlg, szExt);
- ListView_DeleteItem(hListView, iItem);
+ if (DeleteExt(hwndDlg, szExt))
+ {
+ ListView_DeleteItem(hListView, iItem);
+ }
return TRUE;
}
@@ -815,8 +892,9 @@ FileTypesDlg_RemoveExt(HWND hwndDlg)
typedef struct ACTION_DIALOG
{
HWND hwndLB;
- WCHAR ClassName[64];
- WCHAR szAction[64];
+ PFILE_TYPE_GLOBALS pG;
+ PFILE_TYPE_ENTRY pEntry;
+ WCHAR szAction[VERBKEY_CCHMAX];
WCHAR szApp[MAX_PATH];
BOOL bUseDDE;
} ACTION_DIALOG, *PACTION_DIALOG;
@@ -825,7 +903,7 @@ static void
ActionDlg_OnBrowse(HWND hwndDlg, PACTION_DIALOG pNewAct, BOOL bEdit = FALSE)
{
WCHAR szFile[MAX_PATH];
- szFile[0] = 0;
+ szFile[0] = UNICODE_NULL;
WCHAR szFilter[MAX_PATH];
LoadStringW(shell32_hInstance, IDS_EXE_FILTER, szFilter, _countof(szFilter));
@@ -847,6 +925,7 @@ ActionDlg_OnBrowse(HWND hwndDlg, PACTION_DIALOG pNewAct, BOOL bEdit =
FALSE)
if (bEdit)
{
CStringW str = szFile;
+ QuoteAppPathForCommand(str);
str += L" \"%1\"";
SetDlgItemTextW(hwndDlg, IDC_ACTION_APP, str);
}
@@ -986,7 +1065,7 @@ EditActionDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
// set title
CStringW str(MAKEINTRESOURCEW(IDS_EDITING_ACTION));
- str += s_pEditAct->ClassName;
+ str += GetTypeName(s_pEditAct->pEntry, s_pEditAct->pG);
SetWindowTextW(hwndDlg, str);
}
return TRUE;
@@ -1014,40 +1093,51 @@ EditActionDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam)
/////////////////////////////////////////////////////////////////////////////
// EditTypeDlg
-static BOOL
-EditTypeDlg_UpdateEntryIcon(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
- LPCWSTR IconPath, INT IconIndex)
+static void
+EditTypeDlg_Restrict(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
{
PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
+ static const WORD map[] = {
+ FTA_NoEditIcon, IDC_EDITTYPE_CHANGE_ICON,
+ FTA_NoEditDesc, IDC_EDITTYPE_TEXT,
+ FTA_NoNewVerb, IDC_EDITTYPE_NEW,
+ FTA_NoEditVerb, IDC_EDITTYPE_EDIT_BUTTON,
+ FTA_NoRemoveVerb, IDC_EDITTYPE_REMOVE,
+ FTA_NoEditDflt, IDC_EDITTYPE_SET_DEFAULT
+ };
+ for (SIZE_T i = 0; i < _countof(map); i += 2)
+ {
+ if (pEntry->EditFlags & map[i + 0])
+ EnableWindow(GetDlgItem(hwndDlg, map[i + 1]), FALSE);
+ }
+}
- 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);
+static BOOL
+EditTypeDlg_UpdateEntryIcon(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
+{
+ PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
+ WCHAR buf[MAX_PATH];
- bIconSet = (pEntry->hIconLarge && pEntry->hIconSmall);
- }
- if (bIconSet)
- {
- StringCbCopyW(pEntry->IconPath, sizeof(pEntry->IconPath), IconPath);
- pEntry->nIconIndex = IconIndex;
- }
- else
+ pEntry->IconPath[0] = UNICODE_NULL; // I want the default icon
+ Normalize(pEntry);
+ pEntry->DestroyIcons();
+ pEntry->hIconSmall = DoExtractIcon(pEntry->IconPath, pEntry->nIconIndex,
TRUE);
+ if (ExpandEnvironmentStringsW(pEditType->szIconPath, buf, _countof(buf))
&& buf[0])
{
- SetFileTypeEntryDefaultIcon(pEntry);
+ HICON hIco = DoExtractIcon(buf, pEditType->nIconIndex, TRUE);
+ if (hIco)
+ {
+ pEntry->DestroyIcons();
+ pEntry->hIconSmall = hIco;
+ }
}
+ StringCbCopyW(pEntry->IconPath, sizeof(pEntry->IconPath),
pEditType->szIconPath);
+ pEntry->nIconIndex = pEditType->nIconIndex;
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);
+ InitializeDefaultIcons(pEditType->pG);
+ HIMAGELIST himlSmall = pEditType->pG->himlSmall;
INT iSmallImage = ImageList_AddIcon(himlSmall, pEntry->hIconSmall);
- ASSERT(iLargeImage == iSmallImage);
- DBG_UNREFERENCED_LOCAL_VARIABLE(iLargeImage);
INT iItem = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
if (iItem != -1)
@@ -1061,41 +1151,73 @@ EditTypeDlg_UpdateEntryIcon(HWND hwndDlg, PEDITTYPE_DIALOG
pEditType,
static BOOL
EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
- LPCWSTR ClassKey, LPCWSTR ClassName, INT cchName)
+ LPCWSTR TypeName, EDITTYPEFLAGS Etf)
{
PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
-
- if (ClassKey[0] == 0)
- return FALSE;
-
- // create or open class key
+ LPCWSTR ClassKey;
+ HRESULT hr = GetClassKey(*pEntry, ClassKey);
+ BOOL OnlyExt = hr != S_OK;
HKEY hClassKey;
- if (RegCreateKeyExW(HKEY_CLASSES_ROOT, ClassKey, 0, NULL, 0, KEY_WRITE, NULL,
- &hClassKey, NULL) != ERROR_SUCCESS)
+ if (FAILED(hr) || RegCreateKeyExW(HKEY_CLASSES_ROOT, ClassKey, 0, NULL, 0,
+ KEY_QUERY_VALUE |KEY_WRITE, NULL,
+ &hClassKey, NULL) != ERROR_SUCCESS)
{
return FALSE;
}
- // create "DefaultIcon" key
- if (pEntry->IconPath[0])
+ // Refresh the EditFlags
+ DWORD dw;
+ if (GetRegDWORD(hClassKey, L"EditFlags", dw, 0, FALSE) == ERROR_SUCCESS)
+ pEntry->EditFlags = (dw & ~FTA_MODIFYMASK) | (pEntry->EditFlags &
FTA_MODIFYMASK);
+
+ if (!OnlyExt)
{
- HKEY hDefaultIconKey;
- if (RegCreateKeyExW(hClassKey, L"DefaultIcon", 0, NULL, 0, KEY_WRITE,
NULL,
- &hDefaultIconKey, NULL) == ERROR_SUCCESS)
+ // Set class properties
+ RegSetOrDelete(hClassKey, L"EditFlags", REG_DWORD, pEntry->EditFlags
? &pEntry->EditFlags : NULL, 4);
+ if (pEntry->IsExtension())
+ {
+ RegSetOrDelete(hClassKey, L"AlwaysShowExt", REG_SZ, (Etf &
ETF_ALWAYSEXT) ? L"" : NULL, 0);
+ }
+ if (RegKeyExists(hClassKey, L"DocObject"))
+ {
+ LRESULT ec = GetRegDWORD(hClassKey, L"BrowserFlags", dw, 0,
TRUE);
+ if (ec == ERROR_SUCCESS || ec == ERROR_FILE_NOT_FOUND)
+ {
+ dw = (dw & ~8) | ((Etf & ETF_BROWSESAME) ? 0 : 8); // Note: 8
means NOT
+ RegSetOrDelete(hClassKey, L"BrowserFlags", REG_DWORD, dw ?
&dw : NULL, sizeof(dw));
+ }
+ }
+ if (!(pEntry->EditFlags & FTA_NoEditDesc))
{
- WCHAR szText[MAX_PATH];
- StringCbPrintfW(szText, sizeof(szText), L"%s,%d",
- pEntry->IconPath, pEntry->nIconIndex);
+ RegSetString(hClassKey, NULL, TypeName, REG_SZ);
+ pEntry->InvalidateTypeName();
+ }
+ }
- // set icon location
- DWORD dwSize = (lstrlenW(szText) + 1) * sizeof(WCHAR);
- RegSetValueExW(hDefaultIconKey, NULL, 0, REG_EXPAND_SZ, LPBYTE(szText),
dwSize);
+ if (pEntry->IconPath[0] && !(pEntry->EditFlags & FTA_NoEditIcon))
+ {
+ HKEY hDefaultIconKey;
+ if (RegCreateKeyExW(hClassKey, L"DefaultIcon", 0, NULL, 0, KEY_WRITE,
+ NULL, &hDefaultIconKey, NULL) == ERROR_SUCCESS)
+ {
+ DWORD type = REG_SZ;
+ WCHAR buf[ICONLOCATION_CCHMAX];
+ LPCWSTR fmt = L"%s,%d";
+ if (!lstrcmpW(pEntry->IconPath, L"%1"))
+ {
+ fmt = L"%s"; // No icon index for "%1"
+ }
+ else if (StrChrW(pEntry->IconPath, L'%'))
+ {
+ type = REG_EXPAND_SZ;
+ }
+ StringCbPrintfW(buf, sizeof(buf), fmt, pEntry->IconPath,
pEntry->nIconIndex);
+ RegSetString(hDefaultIconKey, NULL, buf, type);
RegCloseKey(hDefaultIconKey);
}
}
- // create "shell" key
HKEY hShellKey;
if (RegCreateKeyExW(hClassKey, L"shell", 0, NULL, 0, KEY_WRITE, NULL,
&hShellKey, NULL) != ERROR_SUCCESS)
@@ -1104,8 +1226,14 @@ EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
return FALSE;
}
+ // set default action
+ if (!(pEntry->EditFlags & FTA_NoEditDflt))
+ {
+ RegSetString(hShellKey, NULL, pEditType->szDefaultVerb, REG_SZ);
+ }
+
// delete shell commands
- WCHAR szVerbName[64];
+ WCHAR szVerbName[VERBKEY_CCHMAX];
DWORD dwIndex = 0;
while (RegEnumKeyW(hShellKey, dwIndex, szVerbName, _countof(szVerbName)) ==
ERROR_SUCCESS)
{
@@ -1120,16 +1248,17 @@ EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
++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);
+ const CStringW& key = pEditType->CommandLineMap.GetKeyAt(i);
+ const CStringW& cmd = pEditType->CommandLineMap.GetValueAt(i);
+ if (!pEditType->ModifiedVerbs.Find(key))
+ {
+ ASSERT(RegKeyExists(hShellKey, key));
+ continue;
+ }
// create verb key
HKEY hVerbKey;
@@ -1141,10 +1270,12 @@ EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
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);
-
+ DWORD dwSize = (cmd.GetLength() + 1) * sizeof(WCHAR);
+ DWORD dwType = REG_SZ;
+ int exp;
+ if ((exp = cmd.Find('%', 0)) >= 0 &&
cmd.Find('%', exp + 1) >= 0)
+ dwType = REG_EXPAND_SZ;
+ RegSetValueExW(hCommandKey, NULL, 0, dwType, LPBYTE(LPCWSTR(cmd)),
dwSize);
RegCloseKey(hCommandKey);
}
@@ -1152,23 +1283,30 @@ EditTypeDlg_WriteClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
}
}
- // 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)
+EditTypeDlg_ReadClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType, EDITTYPEFLAGS &Etf)
{
- // open class key
+ PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
+ LPCWSTR ClassKey;
+ HRESULT hr = GetClassKey(*pEntry, ClassKey);
HKEY hClassKey;
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, ClassKey, 0, KEY_READ, &hClassKey) !=
ERROR_SUCCESS)
+ if (FAILED(hr) || RegOpenKeyExW(HKEY_CLASSES_ROOT, ClassKey, 0, KEY_READ,
&hClassKey))
return FALSE;
+ UINT etfbits = (RegValueExists(hClassKey, L"AlwaysShowExt")) ?
ETF_ALWAYSEXT : 0;
+
+ // 8 in BrowserFlags listed in KB 162059 seems to be our bit
+ BOOL docobj = RegKeyExists(hClassKey, L"DocObject");
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SAME_WINDOW), docobj);
+ etfbits |= (docobj && (GetRegDWORD(hClassKey, L"BrowserFlags")
& 8)) ? 0 : ETF_BROWSESAME;
+
+ Etf = EDITTYPEFLAGS(etfbits);
+
// open "shell" key
HKEY hShellKey;
if (RegOpenKeyExW(hClassKey, L"shell", 0, KEY_READ, &hShellKey) !=
ERROR_SUCCESS)
@@ -1177,7 +1315,7 @@ EditTypeDlg_ReadClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
LPCWSTR ClassKey
return FALSE;
}
- WCHAR DefaultVerb[64];
+ WCHAR DefaultVerb[VERBKEY_CCHMAX];
DWORD dwSize = sizeof(DefaultVerb);
if (RegQueryValueExW(hShellKey, NULL, NULL, NULL,
LPBYTE(DefaultVerb), &dwSize) == ERROR_SUCCESS)
@@ -1190,7 +1328,7 @@ EditTypeDlg_ReadClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
LPCWSTR ClassKey
}
// enumerate shell verbs
- WCHAR szVerbName[64];
+ WCHAR szVerbName[VERBKEY_CCHMAX];
DWORD dwIndex = 0;
while (RegEnumKeyW(hShellKey, dwIndex, szVerbName, _countof(szVerbName)) ==
ERROR_SUCCESS)
{
@@ -1205,7 +1343,7 @@ EditTypeDlg_ReadClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
LPCWSTR ClassKey
if (nResult == ERROR_SUCCESS)
{
// get command line
- WCHAR szValue[MAX_PATH + 32];
+ WCHAR szValue[MAX_PATH * 2];
dwSize = sizeof(szValue);
nResult = RegQueryValueExW(hCommandKey, NULL, NULL, NULL,
LPBYTE(szValue), &dwSize);
if (nResult == ERROR_SUCCESS)
@@ -1222,9 +1360,16 @@ EditTypeDlg_ReadClass(HWND hwndDlg, PEDITTYPE_DIALOG pEditType,
LPCWSTR ClassKey
++dwIndex;
}
+ WCHAR TypeName[TYPENAME_CCHMAX];
+ dwSize = sizeof(TypeName);
+ if (!RegQueryValueExW(hClassKey, NULL, NULL, NULL, LPBYTE(TypeName), &dwSize))
+ {
+ TypeName[_countof(TypeName) - 1] = UNICODE_NULL; // Terminate
+ SetDlgItemTextW(hwndDlg, IDC_EDITTYPE_TEXT, TypeName);
+ }
+
RegCloseKey(hShellKey);
RegCloseKey(hClassKey);
-
return TRUE;
}
@@ -1233,16 +1378,26 @@ 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);
+ WCHAR TypeName[TYPENAME_CCHMAX];
+ GetDlgItemTextW(hwndDlg, IDC_EDITTYPE_TEXT, TypeName, _countof(TypeName));
+ StrTrimW(TypeName, g_pszSpace);
+
+ UINT etf = 0;
+ pEntry->EditFlags &= ~(FTA_MODIFYMASK);
+ if (!SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_CONFIRM_OPEN, BM_GETCHECK, 0, 0))
+ pEntry->EditFlags |= FTA_OpenIsSafe;
+ if (SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_SHOW_EXT, BM_GETCHECK, 0, 0))
+ etf |= ETF_ALWAYSEXT;
+ if (SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_SAME_WINDOW, BM_GETCHECK, 0, 0))
+ etf |= ETF_BROWSESAME;
// update entry icon
- EditTypeDlg_UpdateEntryIcon(hwndDlg, pEditType, pEditType->szIconPath,
pEditType->nIconIndex);
+ EditTypeDlg_UpdateEntryIcon(hwndDlg, pEditType);
// write registry
- EditTypeDlg_WriteClass(hwndDlg, pEditType, pEntry->ClassKey,
pEntry->ClassName,
- _countof(pEntry->ClassName));
+ EditTypeDlg_WriteClass(hwndDlg, pEditType, TypeName, (EDITTYPEFLAGS)etf);
+
+ pEntry->InvalidateDefaultApp();
// update the icon cache
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, NULL, NULL);
@@ -1265,7 +1420,7 @@ EditTypeDlg_OnRemove(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
return FALSE;
// get text
- WCHAR szText[64];
+ WCHAR szText[VERBKEY_CCHMAX];
szText[0] = 0;
SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_GETTEXT, iItem,
(LPARAM)szText);
StrTrimW(szText, g_pszSpace);
@@ -1296,10 +1451,10 @@ EditTypeDlg_OnCommand(HWND hwndDlg, UINT id, UINT code,
PEDITTYPE_DIALOG pEditTy
break;
case IDC_EDITTYPE_NEW:
+ // open 'New Action' dialog
action.bUseDDE = FALSE;
action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
- StringCbPrintfW(action.ClassName, sizeof(action.ClassName),
pEditType->pEntry->ClassName);
- // open 'New Action' dialog
+ action.pEntry = pEditType->pEntry;
if (IDOK == DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_ACTION),
hwndDlg,
NewActionDlgProc, LPARAM(&action)))
{
@@ -1318,8 +1473,10 @@ EditTypeDlg_OnCommand(HWND hwndDlg, UINT id, UINT code,
PEDITTYPE_DIALOG pEditTy
{
// add it
CStringW strCommandLine = action.szApp;
+ QuoteAppPathForCommand(strCommandLine);
strCommandLine += L" \"%1\"";
pEditType->CommandLineMap.SetAt(action.szAction,
strCommandLine);
+ pEditType->ModifiedVerbs.AddHead(action.szAction);
SendMessageW(action.hwndLB, LB_ADDSTRING, 0,
LPARAM(action.szAction));
if (SendMessageW(action.hwndLB, LB_GETCOUNT, 0, 0) == 1)
{
@@ -1345,6 +1502,7 @@ EditTypeDlg_OnCommand(HWND hwndDlg, UINT id, UINT code,
PEDITTYPE_DIALOG pEditTy
{
EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SET_DEFAULT), TRUE);
}
+ EditTypeDlg_Restrict(hwndDlg, pEditType);
break;
}
else if (code != LBN_DBLCLK)
@@ -1356,7 +1514,8 @@ EditTypeDlg_OnCommand(HWND hwndDlg, UINT id, UINT code,
PEDITTYPE_DIALOG pEditTy
case IDC_EDITTYPE_EDIT_BUTTON:
action.bUseDDE = FALSE;
action.hwndLB = GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX);
- StringCbPrintfW(action.ClassName, sizeof(action.ClassName),
pEditType->pEntry->ClassName);
+ action.pG = pEditType->pG;
+ action.pEntry = pEditType->pEntry;
iItem = SendMessageW(action.hwndLB, LB_GETCURSEL, 0, 0);
if (iItem == LB_ERR)
break;
@@ -1378,6 +1537,7 @@ EditTypeDlg_OnCommand(HWND hwndDlg, UINT id, UINT code,
PEDITTYPE_DIALOG pEditTy
SendMessageW(action.hwndLB, LB_DELETESTRING, iItem, 0);
SendMessageW(action.hwndLB, LB_INSERTSTRING, iItem,
LPARAM(action.szAction));
pEditType->CommandLineMap.SetAt(action.szAction, action.szApp);
+ pEditType->ModifiedVerbs.AddHead(action.szAction);
}
break;
@@ -1405,16 +1565,23 @@ static BOOL
EditTypeDlg_OnInitDialog(HWND hwndDlg, PEDITTYPE_DIALOG pEditType)
{
PFILE_TYPE_ENTRY pEntry = pEditType->pEntry;
- StringCbCopyW(pEditType->szIconPath, sizeof(pEditType->szIconPath),
pEntry->IconPath);
+ EDITTYPEFLAGS Etf;
+ ExpandEnvironmentStringsW(pEntry->IconPath, pEditType->szIconPath,
_countof(pEditType->szIconPath));
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);
+ HICON hIco = DoExtractIcon(pEditType->szIconPath, pEditType->nIconIndex);
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_ICON, STM_SETICON, (WPARAM)hIco, 0);
+ EditTypeDlg_ReadClass(hwndDlg, pEditType, Etf);
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_CONFIRM_OPEN, BM_SETCHECK,
!(pEntry->EditFlags & FTA_OpenIsSafe), 0);
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_SHOW_EXT, BM_SETCHECK, !!(Etf &
ETF_ALWAYSEXT), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTYPE_SHOW_EXT), pEntry->IsExtension());
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_SAME_WINDOW, BM_SETCHECK, !!(Etf &
ETF_BROWSESAME), 0);
InvalidateRect(GetDlgItem(hwndDlg, IDC_EDITTYPE_LISTBOX), NULL, TRUE);
+ // select first item
+ SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_SETCURSEL, 0, 0);
// is listbox empty?
if (SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_LISTBOX, LB_GETCOUNT, 0, 0) == 0)
{
@@ -1422,14 +1589,7 @@ EditTypeDlg_OnInitDialog(HWND hwndDlg, PEDITTYPE_DIALOG
pEditType)
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);
-
+ EditTypeDlg_Restrict(hwndDlg, pEditType);
return TRUE;
}
@@ -1447,6 +1607,14 @@ EditTypeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam)
s_pEditType = (PEDITTYPE_DIALOG)lParam;
return EditTypeDlg_OnInitDialog(hwndDlg, s_pEditType);
+ case WM_DESTROY:
+ {
+ HICON hOld = (HICON)SendDlgItemMessageW(hwndDlg, IDC_EDITTYPE_ICON,
STM_GETICON, 0, 0);
+ if (hOld)
+ DestroyIcon(hOld);
+ break;
+ }
+
case WM_DRAWITEM:
pDraw = LPDRAWITEMSTRUCT(lParam);
return EditTypeDlg_OnDrawItem(hwndDlg, pDraw, s_pEditType);
@@ -1469,129 +1637,150 @@ EditTypeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam)
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;
+ PFILE_TYPE_GLOBALS pG = (PFILE_TYPE_GLOBALS)lParamSort;
+ PFILE_TYPE_ENTRY entry1 = (PFILE_TYPE_ENTRY)lParam1, entry2 =
(PFILE_TYPE_ENTRY)lParam2;
+ int x = 0;
+ if (pG->SortCol == 1)
+ x = wcsicmp(GetTypeName(entry1, pG), GetTypeName(entry2, pG));
+ if (!x && !(x = entry1->IsExtension() - entry2->IsExtension()))
+ x = wcsicmp(entry1->FileExtension, entry2->FileExtension);
+ return x * pG->SortReverse;
+}
- return wcsicmp(Entry1->FileDescription, Entry2->FileDescription);
+static void
+FileTypesDlg_Sort(PFILE_TYPE_GLOBALS pG, HWND hListView, INT Column = -1)
+{
+ pG->SortReverse = pG->SortCol == Column ? pG->SortReverse * -1 : 1;
+ pG->SortCol = Column < 0 ? 0 : (INT8) Column;
+ ListView_SortItems(hListView, FileTypesDlg_CompareItems, (LPARAM)pG);
}
static VOID
FileTypesDlg_InitListView(HWND hwndDlg, HWND hListView)
{
RECT clientRect;
- LVCOLUMNW col;
- WCHAR szName[50];
- DWORD dwStyle;
- INT columnSize;
+ LPCWSTR columnName;
+ WCHAR szBuf[50];
- 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;
+ LVCOLUMNW col;
+ col.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
+ col.fmt = 0;
GetClientRect(hListView, &clientRect);
- ZeroMemory(&col, sizeof(LV_COLUMN));
- columnSize = (clientRect.right - clientRect.left) / 4;
+ INT column0Size = (clientRect.right - clientRect.left) / 4;
+
+ columnName = L"Extensions"; // Default to English
+ if (LoadStringW(shell32_hInstance, IDS_COLUMN_EXTENSION, szBuf, _countof(szBuf)))
+ columnName = szBuf;
+ col.pszText = const_cast<LPWSTR>(columnName);
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;
+ col.cx = column0Size;
SendMessageW(hListView, LVM_INSERTCOLUMNW, 0, (LPARAM)&col);
- if (!LoadStringW(shell32_hInstance, IDS_FILE_TYPES, szName, _countof(szName)))
+ columnName = L"File Types"; // Default to English
+ if (LoadStringW(shell32_hInstance, IDS_FILE_TYPES, szBuf, _countof(szBuf)))
+ {
+ columnName = szBuf;
+ }
+ else
{
- // default to english
- wcscpy(szName, L"File Types");
ERR("Failed to load localized string!\n");
}
-
+ col.pszText = const_cast<LPWSTR>(columnName);
col.iSubItem = 1;
- col.cx = clientRect.right - clientRect.left - columnSize -
GetSystemMetrics(SM_CYVSCROLL);
- col.cchTextMax = wcslen(szName);
- col.pszText = szName;
+ col.cx = clientRect.right - clientRect.left - column0Size -
GetSystemMetrics(SM_CYVSCROLL);
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);
+ const UINT lvexstyle = LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP;
+ ListView_SetExtendedListViewStyleEx(hListView, lvexstyle, lvexstyle);
}
-static PFILE_TYPE_ENTRY
-FileTypesDlg_DoList(HWND hwndDlg)
+static void
+FileTypesDlg_SetGroupboxText(HWND hwndDlg, LPCWSTR Assoc)
{
- 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;
+ CStringW buf;
+ buf.Format(IDS_FILE_DETAILS, Assoc);
+ SetDlgItemTextW(hwndDlg, IDC_FILETYPES_DETAILS_GROUPBOX, buf.GetString());
+}
- dwName = _countof(szName);
+static void
+FileTypesDlg_Refresh(HWND hwndDlg, HWND hListView, PFILE_TYPE_GLOBALS pG)
+{
+ ListView_DeleteAllItems(hListView);
+ ImageList_RemoveAll(pG->himlSmall);
+ InitializeDefaultIcons(pG);
+ FileTypesDlg_SetGroupboxText(hwndDlg, L"");
+ SetDlgItemTextW(hwndDlg, IDC_FILETYPES_DESCRIPTION, L"");
+ SetDlgItemTextW(hwndDlg, IDC_FILETYPES_APPNAME, L"");
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILETYPES_DELETE), FALSE);
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE |
RDW_UPDATENOW);
+#if DBG
+ DWORD statTickStart = GetTickCount();
+#endif
+ INT iItem = 0;
+ WCHAR szName[ASSOC_CCHMAX];
+ DWORD dwName = _countof(szName);
+ DWORD dwIndex = 0;
+ SendMessage(hListView, WM_SETREDRAW, FALSE, 0);
while (RegEnumKeyExW(HKEY_CLASSES_ROOT, dwIndex++, szName, &dwName,
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
- if (FileTypesDlg_InsertToLV(hListView, szName, iItem, szFile))
+ if (FileTypesDlg_InsertToLV(hListView, szName, iItem, pG))
++iItem;
dwName = _countof(szName);
}
+ FileTypesDlg_Sort(pG, hListView);
+ SendMessage(hListView, WM_SETREDRAW, TRUE, 0);
+ RedrawWindow(hListView, NULL, NULL, RDW_ALLCHILDREN | RDW_ERASE | RDW_FRAME |
RDW_INVALIDATE);
- // Leave if the list is empty
- if (iItem == 0)
- return NULL;
+#if DBG
+ DbgPrint("FT loaded %u (%ums)\n", iItem, GetTickCount() - statTickStart);
+#endif
+ // select first item
+ ListView_SetItemState(hListView, 0, -1, LVIS_FOCUSED | LVIS_SELECTED);
+}
- // sort list
- ListView_SortItems(hListView, FileTypesDlg_CompareItems, NULL);
+static PFILE_TYPE_GLOBALS
+FileTypesDlg_Initialize(HWND hwndDlg)
+{
+ HWND hListView = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
+ PFILE_TYPE_GLOBALS pG = (PFILE_TYPE_GLOBALS)SHAlloc(sizeof(*pG));
+ if (!pG)
+ return pG;
- // 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);
+ pG->SortReverse = 1;
+ pG->hDefExtIconSmall = NULL;
+ pG->hOpenWithImage = NULL;
+ pG->IconSize = GetSystemMetrics(SM_CXSMICON); // Shell icons are always square
+ pG->himlSmall = ImageList_Create(pG->IconSize, pG->IconSize, ILC_COLOR32 |
ILC_MASK, 256, 20);
+ pG->hHeap = GetProcessHeap();
+
+ if (!LoadStringW(shell32_hInstance, IDS_ANY_FILE,
+ pG->DefExtTypeNameFmt, _countof(pG->DefExtTypeNameFmt)))
+ {
+ LPCWSTR fallback = L"%s File"; // Default to English
+ StringCchCopyW(pG->DefExtTypeNameFmt, _countof(pG->DefExtTypeNameFmt),
fallback);
+ }
+ pG->NoneString[0] = UNICODE_NULL;
+ LoadStringW(shell32_hInstance, IDS_NONE, pG->NoneString,
_countof(pG->NoneString));
+
+ if (!(pG->Restricted = SHRestricted(REST_NOFILEASSOCIATE)))
+ {
+ HKEY hKey;
+ if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Classes", 0, NULL,
0, KEY_WRITE, NULL, &hKey, NULL))
+ pG->Restricted = TRUE;
+ else
+ RegCloseKey(hKey);
+ }
- lvItem.mask = LVIF_PARAM;
- ListView_GetItem(hListView, &lvItem);
+ FileTypesDlg_InitListView(hwndDlg, hListView);
+ ListView_SetImageList(hListView, pG->himlSmall, LVSIL_SMALL);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILETYPES_NEW), !pG->Restricted);
- return (PFILE_TYPE_ENTRY)lvItem.lParam;
+ // Delay loading the items so the propertysheet has time to finalize the UI
+ PostMessage(hListView, WM_KEYDOWN, VK_F5, 0);
+ return pG;
}
static inline PFILE_TYPE_ENTRY
@@ -1621,69 +1810,56 @@ FileTypesDlg_OnDelete(HWND hwndDlg)
FileTypesDlg_RemoveExt(hwndDlg);
// Select first item (Win2k3 does it)
- LV_ITEMW item = { LVIF_STATE };
- item.stateMask = item.state = LVIS_FOCUSED | LVIS_SELECTED;
- item.iItem = 0;
- ListView_SetItem(GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW), &item);
+ HWND hListView = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
+ ListView_SetItemState(hListView, 0, -1, LVIS_FOCUSED | LVIS_SELECTED);
}
}
static void
-FileTypesDlg_OnItemChanging(HWND hwndDlg, PFILE_TYPE_ENTRY pEntry)
+FileTypesDlg_OnItemChanging(HWND hwndDlg, PFILE_TYPE_ENTRY pEntry, PFILE_TYPE_GLOBALS
pG)
{
- 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);
+ HBITMAP &hbmProgram = pG->hOpenWithImage;
+ LPCWSTR DispAssoc = pEntry->GetAssocForDisplay();
+ LPCWSTR TypeName = GetTypeName(pEntry, pG);
+ CStringW buf;
// 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);
+ FileTypesDlg_SetGroupboxText(hwndDlg, DispAssoc);
+ if (pEntry->IsExtension())
+ buf.Format(IDS_FILE_DETAILSADV, DispAssoc, TypeName, TypeName);
+ else
+ buf = L"";
+ SetDlgItemTextW(hwndDlg, IDC_FILETYPES_DESCRIPTION, buf.GetString());
// delete previous program image
- if (s_hbmProgram)
+ if (hbmProgram)
{
- DeleteObject(s_hbmProgram);
- s_hbmProgram = NULL;
+ DeleteObject(hbmProgram);
+ 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");
+ LPCWSTR appname = GetAppName(pEntry);
+ SetDlgItemTextW(hwndDlg, IDC_FILETYPES_APPNAME, appname);
- // 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);
-}
-
-static VOID
-FileTypesDlg_UpdateAppInfo(HWND hwndDlg, PFILE_TYPE_ENTRY pEntry)
-{
- pEntry->ProgramPath[0] = pEntry->AppName[0] = UNICODE_NULL;
-
- DWORD cch = _countof(pEntry->ProgramPath);
- if (S_OK == AssocQueryStringW(ASSOCF_INIT_IGNOREUNKNOWN, ASSOCSTR_EXECUTABLE,
- pEntry->FileExtension, NULL, pEntry->ProgramPath,
&cch))
+ // set program image
+ HICON hIconSm = NULL;
+ LPCWSTR exe = GetProgramPath(pEntry);
+ if (*exe)
{
- QueryFileDescription(pEntry->ProgramPath, pEntry->AppName,
_countof(pEntry->AppName));
+ ExtractIconExW(exe, 0, NULL, &hIconSm, 1);
}
+ hbmProgram = BitmapFromIcon(hIconSm, 16, 16);
+ DestroyIcon(hIconSm);
+ SendDlgItemMessageW(hwndDlg, IDC_FILETYPES_ICON, STM_SETIMAGE, IMAGE_BITMAP,
LPARAM(hbmProgram));
+
+ // Enable/Disable the buttons
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILETYPES_CHANGE),
+ !pG->Restricted && pEntry->IsExtension());
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILETYPES_ADVANCED),
+ !(pEntry->EditFlags & FTA_NoEdit) &&
!pG->Restricted);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILETYPES_DELETE),
+ !(pEntry->EditFlags & FTA_NoRemove) && !pG->Restricted
&& pEntry->IsExtension());
}
// IDD_FOLDER_OPTIONS_FILETYPES
@@ -1694,23 +1870,31 @@ FolderOptionsFileTypesDlg(
WPARAM wParam,
LPARAM lParam)
{
+ PFILE_TYPE_GLOBALS pGlobals = (PFILE_TYPE_GLOBALS)GetWindowLongPtrW(hwndDlg,
DWLP_USER);
+ if (!pGlobals && uMsg != WM_INITDIALOG)
+ return FALSE;
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);
+ pGlobals = FileTypesDlg_Initialize(hwndDlg);
+ SetWindowLongPtrW(hwndDlg, DWLP_USER, (LONG_PTR)pGlobals);
return TRUE;
+ case WM_DESTROY:
+ SetWindowLongPtrW(hwndDlg, DWLP_USER, 0);
+ if (pGlobals)
+ {
+ DestroyIcon(pGlobals->hDefExtIconSmall);
+ DeleteObject(pGlobals->hOpenWithImage);
+ SHFree(pGlobals);
+ }
+ break;
+
case WM_COMMAND:
switch (LOWORD(wParam))
{
@@ -1719,7 +1903,7 @@ FolderOptionsFileTypesDlg(
if (IDOK == DialogBoxParamW(shell32_hInstance,
MAKEINTRESOURCEW(IDD_NEWEXTENSION),
hwndDlg, NewExtDlgProc,
(LPARAM)&newext))
{
- FileTypesDlg_AddExt(hwndDlg, newext.szExt, newext.szFileType);
+ FileTypesDlg_AddExt(hwndDlg, newext.szExt, newext.szFileType,
pGlobals);
}
break;
@@ -1731,26 +1915,24 @@ FolderOptionsFileTypesDlg(
pEntry = FileTypesDlg_GetEntry(GetDlgItem(hwndDlg,
IDC_FILETYPES_LISTVIEW));
if (pEntry)
{
- ZeroMemory(&Info, sizeof(Info));
- Info.oaifInFlags = OAIF_FORCE_REGISTRATION | OAIF_REGISTER_EXT;
- Info.pcszFile = pEntry->FileExtension;
- Info.pcszClass = NULL;
- if (SHOpenWithDialog(hwndDlg, &Info) == S_OK)
+ OPENASINFO oai = { pEntry->FileExtension, 0,
OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT };
+ if (SUCCEEDED(SHOpenWithDialog(hwndDlg, &oai)))
{
- FileTypesDlg_UpdateAppInfo(hwndDlg, pEntry);
- FileTypesDlg_OnItemChanging(hwndDlg, pEntry);
- PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+ pEntry->InvalidateDefaultApp();
+ FileTypesDlg_OnItemChanging(hwndDlg, pEntry, pGlobals);
}
}
break;
case IDC_FILETYPES_ADVANCED:
edittype.hwndLV = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
+ edittype.pG = pGlobals;
edittype.pEntry = FileTypesDlg_GetEntry(edittype.hwndLV);
- if (edittype.pEntry)
+ if (Normalize(edittype.pEntry))
{
DialogBoxParamW(shell32_hInstance,
MAKEINTRESOURCEW(IDD_EDITTYPE),
hwndDlg, EditTypeDlgProc,
(LPARAM)&edittype);
+ FileTypesDlg_OnItemChanging(hwndDlg, edittype.pEntry,
pGlobals);
}
break;
}
@@ -1760,24 +1942,38 @@ FolderOptionsFileTypesDlg(
lppl = (LPNMLISTVIEW) lParam;
switch (lppl->hdr.code)
{
+ case LVN_GETDISPINFO:
+ {
+ LPNMLVDISPINFOW pLVDI = (LPNMLVDISPINFOW)lParam;
+ PFILE_TYPE_ENTRY entry = (PFILE_TYPE_ENTRY)pLVDI->item.lParam;
+ if (entry && (pLVDI->item.mask & LVIF_TEXT))
+ {
+ if (pLVDI->item.iSubItem == 1)
+ {
+ pLVDI->item.pszText = GetTypeName(entry, pGlobals);
+ pLVDI->item.mask |= LVIF_DI_SETITEM;
+ }
+ }
+ break;
+ }
+
case LVN_KEYDOWN:
{
LV_KEYDOWN *pKeyDown = (LV_KEYDOWN *)lParam;
- if (pKeyDown->wVKey == VK_DELETE)
+ switch (pKeyDown->wVKey)
{
- FileTypesDlg_OnDelete(hwndDlg);
+ case VK_DELETE:
+ FileTypesDlg_OnDelete(hwndDlg);
+ break;
+ case VK_F5:
+ FileTypesDlg_Refresh(hwndDlg, pKeyDown->hdr.hwndFrom,
pGlobals);
+ break;
}
break;
}
case NM_DBLCLK:
- edittype.hwndLV = GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW);
- edittype.pEntry = FileTypesDlg_GetEntry(edittype.hwndLV);
- if (edittype.pEntry)
- {
- DialogBoxParamW(shell32_hInstance,
MAKEINTRESOURCEW(IDD_EDITTYPE),
- hwndDlg, EditTypeDlgProc,
(LPARAM)&edittype);
- }
+ SendMessage(hwndDlg, WM_COMMAND, IDC_FILETYPES_ADVANCED, 0);
break;
case LVN_DELETEALLITEMS:
@@ -1787,9 +1983,8 @@ FolderOptionsFileTypesDlg(
pEntry = FileTypesDlg_GetEntry(lppl->hdr.hwndFrom,
lppl->iItem);
if (pEntry)
{
- DestroyIcon(pEntry->hIconLarge);
- DestroyIcon(pEntry->hIconSmall);
- HeapFree(GetProcessHeap(), 0, pEntry);
+ pEntry->DestroyIcons();
+ HeapFree(pGlobals->hHeap, 0, pEntry);
}
return FALSE;
@@ -1802,10 +1997,14 @@ FolderOptionsFileTypesDlg(
if (!(lppl->uOldState & LVIS_FOCUSED) &&
(lppl->uNewState & LVIS_FOCUSED))
{
- FileTypesDlg_OnItemChanging(hwndDlg, pEntry);
+ FileTypesDlg_OnItemChanging(hwndDlg, pEntry, pGlobals);
}
break;
+ case LVN_COLUMNCLICK:
+ FileTypesDlg_Sort(pGlobals, lppl->hdr.hwndFrom,
lppl->iSubItem);
+ break;
+
case PSN_SETACTIVE:
// On page activation, set the focus to the listview
SetFocus(GetDlgItem(hwndDlg, IDC_FILETYPES_LISTVIEW));
diff --git a/dll/win32/shell32/lang/bg-BG.rc b/dll/win32/shell32/lang/bg-BG.rc
index 3f6ca3fdc89..a6f1ec66737 100644
--- a/dll/win32/shell32/lang/bg-BG.rc
+++ b/dll/win32/shell32/lang/bg-BG.rc
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/ca-ES.rc b/dll/win32/shell32/lang/ca-ES.rc
index adb698a148d..518dd4329d6 100644
--- a/dll/win32/shell32/lang/ca-ES.rc
+++ b/dll/win32/shell32/lang/ca-ES.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "System File"
IDS_VXD_FILE "Virtual Device Driver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Open"
IDS_EXPLORE_VERB "Explore"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/cs-CZ.rc b/dll/win32/shell32/lang/cs-CZ.rc
index 95ad5dcc8f7..744d8c727a7 100644
--- a/dll/win32/shell32/lang/cs-CZ.rc
+++ b/dll/win32/shell32/lang/cs-CZ.rc
@@ -998,10 +998,6 @@ BEGIN
IDS_FILE_TYPES "Typy souborů"
IDS_COLUMN_EXTENSION "Přípony"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "Soubor %s"
-
IDS_BYTES_FORMAT "bajtů"
IDS_UNKNOWN_APP "Neznámá aplikace"
IDS_EXE_DESCRIPTION "Popis:"
diff --git a/dll/win32/shell32/lang/da-DK.rc b/dll/win32/shell32/lang/da-DK.rc
index e7b84e57701..7ba29c63939 100644
--- a/dll/win32/shell32/lang/da-DK.rc
+++ b/dll/win32/shell32/lang/da-DK.rc
@@ -972,7 +972,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "System File"
IDS_VXD_FILE "Virtual Device Driver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Open"
IDS_EXPLORE_VERB "Explore"
@@ -997,10 +997,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/de-DE.rc b/dll/win32/shell32/lang/de-DE.rc
index 3f558834d2a..ecb87154a4b 100644
--- a/dll/win32/shell32/lang/de-DE.rc
+++ b/dll/win32/shell32/lang/de-DE.rc
@@ -991,10 +991,6 @@ BEGIN
IDS_FILE_TYPES "Dateitypen"
IDS_COLUMN_EXTENSION "Erweiterungen"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s-Datei"
-
IDS_BYTES_FORMAT "Bytes"
IDS_UNKNOWN_APP "Unbekannte Anwendung"
IDS_EXE_DESCRIPTION "Beschreibung:"
diff --git a/dll/win32/shell32/lang/el-GR.rc b/dll/win32/shell32/lang/el-GR.rc
index 0fd46399191..e26cab3ff42 100644
--- a/dll/win32/shell32/lang/el-GR.rc
+++ b/dll/win32/shell32/lang/el-GR.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "System File"
IDS_VXD_FILE "Virtual Device Driver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Open"
IDS_EXPLORE_VERB "Explore"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/en-GB.rc b/dll/win32/shell32/lang/en-GB.rc
index 0a191cbc16b..7d3e5ef59a8 100644
--- a/dll/win32/shell32/lang/en-GB.rc
+++ b/dll/win32/shell32/lang/en-GB.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "System File"
IDS_VXD_FILE "Virtual Device Driver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Open"
IDS_EXPLORE_VERB "Explore"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/en-US.rc b/dll/win32/shell32/lang/en-US.rc
index 83f1245ea5f..e8195754991 100644
--- a/dll/win32/shell32/lang/en-US.rc
+++ b/dll/win32/shell32/lang/en-US.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "System File"
IDS_VXD_FILE "Virtual Device Driver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Open"
IDS_EXPLORE_VERB "Explore"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/es-ES.rc b/dll/win32/shell32/lang/es-ES.rc
index ed20a44cdcd..0d4e112eada 100644
--- a/dll/win32/shell32/lang/es-ES.rc
+++ b/dll/win32/shell32/lang/es-ES.rc
@@ -999,10 +999,6 @@ BEGIN
IDS_FILE_TYPES "Tipos de archivo"
IDS_COLUMN_EXTENSION "Extensiones"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "Archivo %s"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Aplicación desconocida"
IDS_EXE_DESCRIPTION "Descripción:"
diff --git a/dll/win32/shell32/lang/et-EE.rc b/dll/win32/shell32/lang/et-EE.rc
index 056706f257f..67324abb2da 100644
--- a/dll/win32/shell32/lang/et-EE.rc
+++ b/dll/win32/shell32/lang/et-EE.rc
@@ -997,10 +997,6 @@ BEGIN
IDS_FILE_TYPES "Failitüübid"
IDS_COLUMN_EXTENSION "Laiendused"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s Fail"
-
IDS_BYTES_FORMAT "baiti"
IDS_UNKNOWN_APP "Tundmatu rakendus"
IDS_EXE_DESCRIPTION "Kirjeldus:"
diff --git a/dll/win32/shell32/lang/eu-ES.rc b/dll/win32/shell32/lang/eu-ES.rc
index a94192b88ca..0eb4c03261c 100644
--- a/dll/win32/shell32/lang/eu-ES.rc
+++ b/dll/win32/shell32/lang/eu-ES.rc
@@ -995,10 +995,6 @@ BEGIN
IDS_FILE_TYPES "Fitxategi-mota"
IDS_COLUMN_EXTENSION "Luzapena"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s fitxategi"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Aplikazio ezezaguna"
IDS_EXE_DESCRIPTION "Deskribapena:"
diff --git a/dll/win32/shell32/lang/fi-FI.rc b/dll/win32/shell32/lang/fi-FI.rc
index cb68d3b4682..6243ce56153 100644
--- a/dll/win32/shell32/lang/fi-FI.rc
+++ b/dll/win32/shell32/lang/fi-FI.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "System File"
IDS_VXD_FILE "Virtual Device Driver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Open"
IDS_EXPLORE_VERB "Explore"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/fr-FR.rc b/dll/win32/shell32/lang/fr-FR.rc
index 8304728dffa..0bb74655ef3 100644
--- a/dll/win32/shell32/lang/fr-FR.rc
+++ b/dll/win32/shell32/lang/fr-FR.rc
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "Types de fichiers"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "Fichier %s"
-
IDS_BYTES_FORMAT "octets"
IDS_UNKNOWN_APP "Application inconnue"
IDS_EXE_DESCRIPTION "Description :"
diff --git a/dll/win32/shell32/lang/he-IL.rc b/dll/win32/shell32/lang/he-IL.rc
index c56e94f7f9d..5f3bd630847 100644
--- a/dll/win32/shell32/lang/he-IL.rc
+++ b/dll/win32/shell32/lang/he-IL.rc
@@ -997,10 +997,6 @@ BEGIN
IDS_FILE_TYPES "סוגי קבצים"
IDS_COLUMN_EXTENSION "סיומות"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "קובץ %s"
-
IDS_BYTES_FORMAT "בתים"
IDS_UNKNOWN_APP "יישום לא ידוע"
IDS_EXE_DESCRIPTION "תיאור:"
diff --git a/dll/win32/shell32/lang/hi-IN.rc b/dll/win32/shell32/lang/hi-IN.rc
index 5029f8f50c4..8a6ed3d42b3 100644
--- a/dll/win32/shell32/lang/hi-IN.rc
+++ b/dll/win32/shell32/lang/hi-IN.rc
@@ -992,10 +992,6 @@ BEGIN
IDS_FILE_TYPES "फ़ाइल प्रकारों"
IDS_COLUMN_EXTENSION "एक्सटेंशन"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s फ़ाइल"
-
IDS_BYTES_FORMAT "बाइट्स"
IDS_UNKNOWN_APP "अनजान ऐप्लिकेशन"
IDS_EXE_DESCRIPTION "विवरण:"
diff --git a/dll/win32/shell32/lang/hu-HU.rc b/dll/win32/shell32/lang/hu-HU.rc
index b7e3dd8dc69..dca369f41aa 100644
--- a/dll/win32/shell32/lang/hu-HU.rc
+++ b/dll/win32/shell32/lang/hu-HU.rc
@@ -989,10 +989,6 @@ BEGIN
IDS_FILE_TYPES "Fájltípusok"
IDS_COLUMN_EXTENSION "Kiterjesztések"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s fájl"
-
IDS_BYTES_FORMAT "bájt"
IDS_UNKNOWN_APP "Ismeretlen alkalmazás"
IDS_EXE_DESCRIPTION "Leírás:"
diff --git a/dll/win32/shell32/lang/id-ID.rc b/dll/win32/shell32/lang/id-ID.rc
index 0a3ce0c2e23..14851b34ba0 100644
--- a/dll/win32/shell32/lang/id-ID.rc
+++ b/dll/win32/shell32/lang/id-ID.rc
@@ -987,10 +987,6 @@ BEGIN
IDS_FILE_TYPES "Jenis Berkas"
IDS_COLUMN_EXTENSION "Ekstensi"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "Berkas %s"
-
IDS_BYTES_FORMAT "byte"
IDS_UNKNOWN_APP "Aplikasi tidak diketahui"
IDS_EXE_DESCRIPTION "Deskripsi:"
diff --git a/dll/win32/shell32/lang/it-IT.rc b/dll/win32/shell32/lang/it-IT.rc
index 5cc05d35a9a..2f06fb39638 100644
--- a/dll/win32/shell32/lang/it-IT.rc
+++ b/dll/win32/shell32/lang/it-IT.rc
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "Tipi di file"
IDS_COLUMN_EXTENSION "Estensioni"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "byte"
IDS_UNKNOWN_APP "Applicazione sconosciuta"
IDS_EXE_DESCRIPTION "Descrizione:"
diff --git a/dll/win32/shell32/lang/ja-JP.rc b/dll/win32/shell32/lang/ja-JP.rc
index 5eaa0bac54f..b4002272715 100644
--- a/dll/win32/shell32/lang/ja-JP.rc
+++ b/dll/win32/shell32/lang/ja-JP.rc
@@ -987,10 +987,6 @@ BEGIN
IDS_FILE_TYPES "ファイルの種類"
IDS_COLUMN_EXTENSION "拡張子"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s ファイル"
-
IDS_BYTES_FORMAT "バイト"
IDS_UNKNOWN_APP "未知のアプリ"
IDS_EXE_DESCRIPTION "説明:"
diff --git a/dll/win32/shell32/lang/ko-KR.rc b/dll/win32/shell32/lang/ko-KR.rc
index 721a9433616..2e4478491ba 100644
--- a/dll/win32/shell32/lang/ko-KR.rc
+++ b/dll/win32/shell32/lang/ko-KR.rc
@@ -972,7 +972,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "System File"
IDS_VXD_FILE "Virtual Device Driver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Open"
IDS_EXPLORE_VERB "Explore"
@@ -997,10 +997,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/nl-NL.rc b/dll/win32/shell32/lang/nl-NL.rc
index 85fe4161723..f3c20c78acc 100644
--- a/dll/win32/shell32/lang/nl-NL.rc
+++ b/dll/win32/shell32/lang/nl-NL.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "System File"
IDS_VXD_FILE "Virtual Device Driver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Open"
IDS_EXPLORE_VERB "Explore"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/no-NO.rc b/dll/win32/shell32/lang/no-NO.rc
index 85d13ec384e..c0f8bd18da8 100644
--- a/dll/win32/shell32/lang/no-NO.rc
+++ b/dll/win32/shell32/lang/no-NO.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "Systemfil"
IDS_VXD_FILE "Virtuell enhetdriver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s fil"
IDS_OPEN_VERB "Åpne"
IDS_EXPLORE_VERB "Explore"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/pl-PL.rc b/dll/win32/shell32/lang/pl-PL.rc
index 1a9f21e4ad8..e495ffef72b 100644
--- a/dll/win32/shell32/lang/pl-PL.rc
+++ b/dll/win32/shell32/lang/pl-PL.rc
@@ -999,10 +999,6 @@ BEGIN
IDS_FILE_TYPES "Typy plików"
IDS_COLUMN_EXTENSION "Rozszerzenia"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "Plik %s"
-
IDS_BYTES_FORMAT "bajtów"
IDS_UNKNOWN_APP "Nieznana aplikacja"
IDS_EXE_DESCRIPTION "Opis:"
diff --git a/dll/win32/shell32/lang/pt-BR.rc b/dll/win32/shell32/lang/pt-BR.rc
index 8aaf2f5b722..16d1422681e 100644
--- a/dll/win32/shell32/lang/pt-BR.rc
+++ b/dll/win32/shell32/lang/pt-BR.rc
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensões"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Aplicativo desconhecido"
IDS_EXE_DESCRIPTION "Descrição:"
diff --git a/dll/win32/shell32/lang/pt-PT.rc b/dll/win32/shell32/lang/pt-PT.rc
index 9fe1d302376..2ca5756dc8e 100644
--- a/dll/win32/shell32/lang/pt-PT.rc
+++ b/dll/win32/shell32/lang/pt-PT.rc
@@ -999,10 +999,6 @@ BEGIN
IDS_FILE_TYPES "Tipos de ficheiro"
IDS_COLUMN_EXTENSION "Extensões"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "Ficheiro %s"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Aplicação desconhecida"
IDS_EXE_DESCRIPTION "Descrição:"
diff --git a/dll/win32/shell32/lang/ro-RO.rc b/dll/win32/shell32/lang/ro-RO.rc
index 02d56b8673d..540d87c9b24 100644
--- a/dll/win32/shell32/lang/ro-RO.rc
+++ b/dll/win32/shell32/lang/ro-RO.rc
@@ -998,12 +998,9 @@ BEGIN
IDS_FILE_TYPES "Tipuri"
IDS_COLUMN_EXTENSION "Extensii"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "Fişier %s"
-
IDS_BYTES_FORMAT "octeţi"
IDS_UNKNOWN_APP "Aplicaţie nespecificată"
+
IDS_EXE_DESCRIPTION "Descriere:"
IDS_MENU_EMPTY "(Gol)"
diff --git a/dll/win32/shell32/lang/ru-RU.rc b/dll/win32/shell32/lang/ru-RU.rc
index 44d9255511c..773dde053f5 100644
--- a/dll/win32/shell32/lang/ru-RU.rc
+++ b/dll/win32/shell32/lang/ru-RU.rc
@@ -999,10 +999,6 @@ BEGIN
IDS_FILE_TYPES "Типы файлов"
IDS_COLUMN_EXTENSION "Расширения"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "Файл %s"
-
IDS_BYTES_FORMAT "байт"
IDS_UNKNOWN_APP "Неизвестное приложение"
IDS_EXE_DESCRIPTION "Описание:"
diff --git a/dll/win32/shell32/lang/sk-SK.rc b/dll/win32/shell32/lang/sk-SK.rc
index b05b408be0e..59bb8bf6097 100644
--- a/dll/win32/shell32/lang/sk-SK.rc
+++ b/dll/win32/shell32/lang/sk-SK.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "Systémový súbor"
IDS_VXD_FILE "Ovládač virtuálneho zariadenia"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Otvoriť"
IDS_EXPLORE_VERB "Explore"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/sl-SI.rc b/dll/win32/shell32/lang/sl-SI.rc
index bc1b6d1c70d..516ea2483f2 100644
--- a/dll/win32/shell32/lang/sl-SI.rc
+++ b/dll/win32/shell32/lang/sl-SI.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Screen Saver"
IDS_SYS_FILE "System File"
IDS_VXD_FILE "Virtual Device Driver"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s File"
IDS_OPEN_VERB "Open"
IDS_EXPLORE_VERB "Explore"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "File Types"
IDS_COLUMN_EXTENSION "Extensions"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
IDS_EXE_DESCRIPTION "Description:"
diff --git a/dll/win32/shell32/lang/sq-AL.rc b/dll/win32/shell32/lang/sq-AL.rc
index c1f0973b65d..fcf87e2f734 100644
--- a/dll/win32/shell32/lang/sq-AL.rc
+++ b/dll/win32/shell32/lang/sq-AL.rc
@@ -997,10 +997,6 @@ BEGIN
IDS_FILE_TYPES "TipiDokumentit"
IDS_COLUMN_EXTENSION "Prapashtesa"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s File"
-
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Aplikacion panjohur"
IDS_EXE_DESCRIPTION "Përshkrimi:"
diff --git a/dll/win32/shell32/lang/sv-SE.rc b/dll/win32/shell32/lang/sv-SE.rc
index 929bbd914b7..9d5486e743d 100644
--- a/dll/win32/shell32/lang/sv-SE.rc
+++ b/dll/win32/shell32/lang/sv-SE.rc
@@ -965,7 +965,7 @@ BEGIN
IDS_SCR_FILE "Skärmsläckare"
IDS_SYS_FILE "Systemfil"
IDS_VXD_FILE "Virtuell enhetsdrivruting"
- IDS_ANY_FILE "%s-file"
+ IDS_ANY_FILE "%s-fil"
IDS_OPEN_VERB "Öppna"
IDS_EXPLORE_VERB "Utforska"
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "Filtyper"
IDS_COLUMN_EXTENSION "Filändelse"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s-fil"
-
IDS_BYTES_FORMAT "byte"
IDS_UNKNOWN_APP "Okänt program"
IDS_EXE_DESCRIPTION "Beskrivning:"
diff --git a/dll/win32/shell32/lang/tr-TR.rc b/dll/win32/shell32/lang/tr-TR.rc
index c8bbcc708a8..2d52e60d51d 100644
--- a/dll/win32/shell32/lang/tr-TR.rc
+++ b/dll/win32/shell32/lang/tr-TR.rc
@@ -999,10 +999,6 @@ BEGIN
IDS_FILE_TYPES "Dosya Türleri"
IDS_COLUMN_EXTENSION "Uzantılar"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s Dosyası"
-
IDS_BYTES_FORMAT "bit"
IDS_UNKNOWN_APP "Bilinmeyen Uygulama"
IDS_EXE_DESCRIPTION "Tanım:"
diff --git a/dll/win32/shell32/lang/uk-UA.rc b/dll/win32/shell32/lang/uk-UA.rc
index b382287c6b8..853f4041a02 100644
--- a/dll/win32/shell32/lang/uk-UA.rc
+++ b/dll/win32/shell32/lang/uk-UA.rc
@@ -990,10 +990,6 @@ BEGIN
IDS_FILE_TYPES "Типи Файлів"
IDS_COLUMN_EXTENSION "Розширення"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "Файл %s"
-
IDS_BYTES_FORMAT "байт"
IDS_UNKNOWN_APP "Невідома програма"
IDS_EXE_DESCRIPTION "Опис:"
diff --git a/dll/win32/shell32/lang/zh-CN.rc b/dll/win32/shell32/lang/zh-CN.rc
index 501eda39614..3d58230cc58 100644
--- a/dll/win32/shell32/lang/zh-CN.rc
+++ b/dll/win32/shell32/lang/zh-CN.rc
@@ -1000,10 +1000,6 @@ BEGIN
IDS_FILE_TYPES "文件类型"
IDS_COLUMN_EXTENSION "扩展名"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s 文件"
-
IDS_BYTES_FORMAT "字节"
IDS_UNKNOWN_APP "未知应用程序"
IDS_EXE_DESCRIPTION "描述:"
diff --git a/dll/win32/shell32/lang/zh-HK.rc b/dll/win32/shell32/lang/zh-HK.rc
index b67aae92952..e4700b57e72 100644
--- a/dll/win32/shell32/lang/zh-HK.rc
+++ b/dll/win32/shell32/lang/zh-HK.rc
@@ -998,10 +998,6 @@ BEGIN
IDS_FILE_TYPES "檔案類型"
IDS_COLUMN_EXTENSION "副檔名"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s 檔案"
-
IDS_BYTES_FORMAT "位元組"
IDS_UNKNOWN_APP "不明應用程式"
IDS_EXE_DESCRIPTION "描述:"
diff --git a/dll/win32/shell32/lang/zh-TW.rc b/dll/win32/shell32/lang/zh-TW.rc
index c4e5ec18405..2bc2ea7d49f 100644
--- a/dll/win32/shell32/lang/zh-TW.rc
+++ b/dll/win32/shell32/lang/zh-TW.rc
@@ -999,10 +999,6 @@ BEGIN
IDS_FILE_TYPES "檔案類型"
IDS_COLUMN_EXTENSION "副檔名"
- /* As in 'INI File' or 'WAV File', fallback string for no-name
extensions
- used in the _File type_ tab of the _Folder Options_ dialog */
- IDS_FILE_EXT_TYPE "%s 檔案"
-
IDS_BYTES_FORMAT "位元組"
IDS_UNKNOWN_APP "未知應用程式"
IDS_EXE_DESCRIPTION "描述:"
diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h
index 8389048af63..97fd073ab6d 100644
--- a/dll/win32/shell32/precomp.h
+++ b/dll/win32/shell32/precomp.h
@@ -111,6 +111,7 @@
#include "CUserNotification.h"
#include "dialogs/folder_options.h"
#include "shelldesktop/CChangeNotifyServer.h"
+#include "utils.h"
#include <wine/debug.h>
#include <wine/unicode.h>
diff --git a/dll/win32/shell32/shresdef.h b/dll/win32/shell32/shresdef.h
index 6721e625e5d..d4c8422d29a 100644
--- a/dll/win32/shell32/shresdef.h
+++ b/dll/win32/shell32/shresdef.h
@@ -188,7 +188,6 @@
#define IDS_FILE_TYPES 174
#define IDS_FILE_DETAILS 175
#define IDS_FILE_DETAILSADV 176
-#define IDS_FILE_EXT_TYPE 999
#define IDS_BYTES_FORMAT 177
#define IDS_OPEN_WITH_RECOMMENDED 178
#define IDS_OPEN_WITH_OTHER 179
diff --git a/dll/win32/shell32/utils.h b/dll/win32/shell32/utils.h
new file mode 100644
index 00000000000..92a96888c5d
--- /dev/null
+++ b/dll/win32/shell32/utils.h
@@ -0,0 +1,47 @@
+/*
+ * PROJECT: shell32
+ * LICENSE: LGPL-2.1+ (
https://spdx.org/licenses/LGPL-2.1+)
+ * PURPOSE: Utility functions
+ * COPYRIGHT: ReactOS Team
+ */
+
+#pragma once
+
+inline BOOL
+RegValueExists(HKEY hKey, LPCWSTR Name)
+{
+ return RegQueryValueExW(hKey, Name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
+}
+
+inline BOOL
+RegKeyExists(HKEY hKey, LPCWSTR Path)
+{
+ BOOL ret = !RegOpenKeyExW(hKey, Path, 0, MAXIMUM_ALLOWED, &hKey);
+ if (ret)
+ RegCloseKey(hKey);
+ return ret;
+}
+
+inline DWORD
+RegSetOrDelete(HKEY hKey, LPCWSTR Name, DWORD Type, LPCVOID Data, DWORD Size)
+{
+ if (Data)
+ return RegSetValueExW(hKey, Name, 0, Type, LPBYTE(Data), Size);
+ else
+ return RegDeleteValueW(hKey, Name);
+}
+
+inline DWORD
+RegSetString(HKEY hKey, LPCWSTR Name, LPCWSTR Str, DWORD Type = REG_SZ)
+{
+ return RegSetValueExW(hKey, Name, 0, Type, LPBYTE(Str), (lstrlenW(Str) + 1) *
sizeof(WCHAR));
+}
+
+// SHExtractIconsW is a forward, use this function instead inside shell32
+inline HICON
+SHELL32_SHExtractIcon(LPCWSTR File, int Index, int cx, int cy)
+{
+ HICON hIco;
+ int r = PrivateExtractIconsW(File, Index, cx, cy, &hIco, NULL, 1, 0);
+ return r > 0 ? hIco : NULL;
+}
diff --git a/sdk/include/psdk/shlwapi.h b/sdk/include/psdk/shlwapi.h
index 8ca1e7544dc..547cf01ea8a 100644
--- a/sdk/include/psdk/shlwapi.h
+++ b/sdk/include/psdk/shlwapi.h
@@ -644,6 +644,32 @@ typedef enum
ASSOCENUM_NONE
} ASSOCENUM;
+typedef enum
+{
+ FTA_None = 0x00000000,
+ FTA_Exclude = 0x00000001,
+ FTA_Show = 0x00000002,
+ FTA_HasExtension = 0x00000004,
+ FTA_NoEdit = 0x00000008,
+ FTA_NoRemove = 0x00000010,
+ FTA_NoNewVerb = 0x00000020,
+ FTA_NoEditVerb = 0x00000040,
+ FTA_NoRemoveVerb = 0x00000080,
+ FTA_NoEditDesc = 0x00000100,
+ FTA_NoEditIcon = 0x00000200,
+ FTA_NoEditDflt = 0x00000400,
+ FTA_NoEditVerbCmd = 0x00000800,
+ FTA_NoEditVerbExe = 0x00001000,
+ FTA_NoDDE = 0x00002000,
+ FTA_NoEditMIME = 0x00008000,
+ FTA_OpenIsSafe = 0x00010000,
+ FTA_AlwaysUnsafe = 0x00020000,
+ FTA_NoRecentDocs = 0x00100000,
+ FTA_SafeForElevation = 0x00200000, /* Win8+ */
+ FTA_AlwaysUseDirectInvoke = 0x00400000 /* Win8+ */
+} FILETYPEATTRIBUTEFLAGS;
+DEFINE_ENUM_FLAG_OPERATORS(FILETYPEATTRIBUTEFLAGS)
+
typedef struct IQueryAssociations *LPQUERYASSOCIATIONS;
#define INTERFACE IQueryAssociations