From c7a73765457955eb19544ec1e93557a19cf5c32b Mon Sep 17 00:00:00 2001 From: Whindmar Saksit Date: Sun, 8 Jun 2025 20:04:10 +0200 Subject: [PATCH] [SHELL32] Implement basic SHMultiFileProperties (#7956) CORE-12510 CORE-20217 --- dll/win32/shell32/dialogs/filedefext.cpp | 588 ++++++++++++------- dll/win32/shell32/dialogs/filedefext.h | 28 +- dll/win32/shell32/dialogs/item_prop.cpp | 25 +- dll/win32/shell32/folders/CDesktopFolder.cpp | 10 +- dll/win32/shell32/lang/bg-BG.rc | 3 + dll/win32/shell32/lang/ca-ES.rc | 5 +- dll/win32/shell32/lang/cs-CZ.rc | 3 + dll/win32/shell32/lang/da-DK.rc | 5 +- dll/win32/shell32/lang/de-DE.rc | 3 + dll/win32/shell32/lang/el-GR.rc | 5 +- dll/win32/shell32/lang/en-GB.rc | 5 +- dll/win32/shell32/lang/en-US.rc | 5 +- dll/win32/shell32/lang/es-ES.rc | 3 + dll/win32/shell32/lang/et-EE.rc | 3 + dll/win32/shell32/lang/eu-ES.rc | 3 + dll/win32/shell32/lang/fi-FI.rc | 5 +- dll/win32/shell32/lang/fr-FR.rc | 3 + dll/win32/shell32/lang/he-IL.rc | 3 + dll/win32/shell32/lang/hi-IN.rc | 3 + dll/win32/shell32/lang/hu-HU.rc | 3 + dll/win32/shell32/lang/id-ID.rc | 3 + dll/win32/shell32/lang/it-IT.rc | 3 + dll/win32/shell32/lang/ja-JP.rc | 3 + dll/win32/shell32/lang/ko-KR.rc | 3 + dll/win32/shell32/lang/nl-NL.rc | 5 +- dll/win32/shell32/lang/no-NO.rc | 3 + dll/win32/shell32/lang/pl-PL.rc | 3 + dll/win32/shell32/lang/pt-BR.rc | 3 + dll/win32/shell32/lang/pt-PT.rc | 3 + dll/win32/shell32/lang/ro-RO.rc | 3 + dll/win32/shell32/lang/ru-RU.rc | 3 + dll/win32/shell32/lang/sk-SK.rc | 3 + dll/win32/shell32/lang/sl-SI.rc | 5 +- dll/win32/shell32/lang/sq-AL.rc | 3 + dll/win32/shell32/lang/sv-SE.rc | 3 + dll/win32/shell32/lang/tr-TR.rc | 3 + dll/win32/shell32/lang/uk-UA.rc | 3 + dll/win32/shell32/lang/zh-CN.rc | 3 + dll/win32/shell32/lang/zh-HK.rc | 3 + dll/win32/shell32/lang/zh-TW.rc | 4 + dll/win32/shell32/precomp.h | 7 + dll/win32/shell32/shresdef.h | 4 + dll/win32/shell32/stubs.cpp | 24 - dll/win32/shell32/utils.cpp | 23 + dll/win32/shell32/wine/pidl.c | 44 +- sdk/include/reactos/shellutils.h | 3 - 46 files changed, 610 insertions(+), 271 deletions(-) diff --git a/dll/win32/shell32/dialogs/filedefext.cpp b/dll/win32/shell32/dialogs/filedefext.cpp index ce7f1dbe3f2..963c2ab8021 100644 --- a/dll/win32/shell32/dialogs/filedefext.cpp +++ b/dll/win32/shell32/dialogs/filedefext.cpp @@ -29,54 +29,92 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath); -BOOL GetPhysicalFileSize(LPCWSTR PathBuffer, PULARGE_INTEGER Size) +static BOOL SH32_GetFileFindData(PCWSTR pszPath, WIN32_FIND_DATAW *pWFD) { - UNICODE_STRING FileName; - OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hFind = FindFirstFileW(pszPath, pWFD); + return hFind != INVALID_HANDLE_VALUE ? FindClose(hFind) : FALSE; +} + +BOOL GetPhysicalFileSize(LPCWSTR pszPath, PULARGE_INTEGER Size) +{ + HANDLE hFile = CreateFileW(pszPath, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | + FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, + FILE_FLAG_OPEN_NO_RECALL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + ERR("Failed to open file for GetPhysicalFileSize\n"); + return FALSE; + } + IO_STATUS_BLOCK IoStatusBlock; - HANDLE FileHandle; FILE_STANDARD_INFORMATION FileInfo; + NTSTATUS Status = NtQueryInformationFile(hFile, &IoStatusBlock, &FileInfo, + sizeof(FileInfo), FileStandardInformation); + if (NT_SUCCESS(Status)) + { + Size->QuadPart = FileInfo.AllocationSize.QuadPart; + } + else + { + ERR("NtQueryInformationFile failed for %S (Status: %08lX)\n", pszPath, Status); + } + CloseHandle(hFile); + return NT_SUCCESS(Status); +} + +static UINT +GetFileStats(HANDLE hFile, PULARGE_INTEGER pVirtSize, PULARGE_INTEGER pPhysSize) +{ NTSTATUS Status; - - if (!RtlDosPathNameToNtPathName_U(PathBuffer, &FileName, NULL, NULL)) - { - ERR("RtlDosPathNameToNtPathName_U failed\n"); - return FALSE; - } - - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = NtOpenFile(&FileHandle, - FILE_READ_ATTRIBUTES | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - FILE_SHARE_READ, - FILE_SYNCHRONOUS_IO_NONALERT); - RtlFreeUnicodeString(&FileName); + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION BasicInfo; + Status = NtQueryInformationFile(hFile, &IoStatusBlock, &BasicInfo, sizeof(BasicInfo), FileBasicInformation); if (!NT_SUCCESS(Status)) + return INVALID_FILE_ATTRIBUTES; + + if ((pVirtSize || pPhysSize) && !(BasicInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - ERR("NtOpenFile failed for %S (Status 0x%08lx)\n", PathBuffer, Status); - return FALSE; + FILE_STANDARD_INFORMATION FileInfo; + Status = NtQueryInformationFile(hFile, &IoStatusBlock, &FileInfo, + sizeof(FileInfo), FileStandardInformation); + if (!NT_SUCCESS(Status)) + return INVALID_FILE_ATTRIBUTES; + if (pVirtSize) + pVirtSize->QuadPart = FileInfo.EndOfFile.QuadPart; + if (pPhysSize) + pPhysSize->QuadPart = FileInfo.AllocationSize.QuadPart; + } + return BasicInfo.FileAttributes; +} + +static UINT +GetFileStats(PCWSTR pszPath, PULARGE_INTEGER pVirtSize, PULARGE_INTEGER pPhysSize) +{ + HANDLE hFile = CreateFileW(pszPath, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | + FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_NO_RECALL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + UINT Attrib = GetFileStats(hFile, pVirtSize, pPhysSize); + CloseHandle(hFile); + return Attrib; } - /* Query the file size */ - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FileInfo), - FileStandardInformation); - NtClose(FileHandle); - if (!NT_SUCCESS(Status)) + WIN32_FIND_DATAW Data; + if (!SH32_GetFileFindData(pszPath, &Data)) + return INVALID_FILE_ATTRIBUTES; + if (pVirtSize) { - ERR("NtQueryInformationFile failed for %S (Status: %08lX)\n", PathBuffer, Status); - return FALSE; + pVirtSize->u.LowPart = Data.nFileSizeLow; + pVirtSize->u.HighPart = Data.nFileSizeHigh; } - - Size->QuadPart = FileInfo.AllocationSize.QuadPart; - return TRUE; + if (pPhysSize) + { + pPhysSize->u.LowPart = Data.nFileSizeLow; + pPhysSize->u.HighPart = Data.nFileSizeHigh; + // TODO: Should we round up to cluster size? + } + return Data.dwFileAttributes; } BOOL CFileVersionInfo::Load(LPCWSTR pwszPath) @@ -545,18 +583,9 @@ CFileDefExt::InitFileAttr(HWND hwndDlg) * structure for both the GetFileAttributesEx and FindFirstFile calls. */ - Success = GetFileAttributesExW(m_wszPath, - GetFileExInfoStandard, + Success = GetFileAttributesExW(m_wszPath, GetFileExInfoStandard, (LPWIN32_FILE_ATTRIBUTE_DATA)&FileInfo); - if (!Success) - { - HANDLE hFind = FindFirstFileW(m_wszPath, &FileInfo); - Success = (hFind != INVALID_HANDLE_VALUE); - if (Success) - FindClose(hFind); - } - - if (Success) + if (Success || (Success = SH32_GetFileFindData(m_wszPath, &FileInfo)) != FALSE) { /* Update attribute checkboxes */ if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) @@ -600,29 +629,11 @@ CFileDefExt::InitFileAttr(HWND hwndDlg) if (m_bDir) { - /* For directories files have to be counted */ - - _CountFolderAndFilesData *data = static_cast<_CountFolderAndFilesData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(_CountFolderAndFilesData))); - data->This = this; - data->pwszBuf = static_cast(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR) * MAX_PATH)); - data->hwndDlg = hwndDlg; - this->AddRef(); - StringCchCopyW(data->pwszBuf, MAX_PATH, m_wszPath); - - SHCreateThread(CFileDefExt::_CountFolderAndFilesThreadProc, data, NULL, NULL); - - /* Update size field */ - if (SH_FormatFileSizeWithBytes(&m_DirSize, wszBuf, _countof(wszBuf))) - SetDlgItemTextW(hwndDlg, 14011, wszBuf); - - if (SH_FormatFileSizeWithBytes(&m_DirSizeOnDisc, wszBuf, _countof(wszBuf))) - SetDlgItemTextW(hwndDlg, 14012, wszBuf); - - /* Display files and folders count */ - WCHAR wszFormat[256]; - LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, wszFormat, _countof(wszFormat)); - StringCchPrintfW(wszBuf, _countof(wszBuf), wszFormat, m_cFiles, m_cFolders); - SetDlgItemTextW(hwndDlg, 14027, wszBuf); + // For directories, files have to be counted + m_hWndDirStatsDlg = hwndDlg; + AddRef(); + if (!SHCreateThread(_CountFolderAndFilesThreadProc, this, 0, NULL)) + Release(); } /* Hide Advanced button. TODO: Implement advanced dialog and enable this button if filesystem supports compression or encryption */ @@ -787,13 +798,280 @@ CFileDefExt::GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar pFileDefExt->InitGeneralPage(hwndDlg); return FALSE; // continue } - default: + case WM_DESTROY: + InterlockedIncrement(&pFileDefExt->m_Destroyed); + break; + case WM_UPDATEDIRSTATS: + pFileDefExt->UpdateDirStatsResults(); break; } return FALSE; } +struct DIRTREESTATS +{ + PDWORD pDirCount, pFileCount; + PULARGE_INTEGER pTotVirtSize, pTotPhysSize; + UINT nTick; + UINT fAttribSet, fAttribAll; + BOOL bMultipleTypes; + BOOL bDeepRecurse; + WCHAR szType[max(100, RTL_FIELD_SIZE(SHFILEINFOA, szTypeName))]; +}; + +void +CFileDefExt::UpdateDirStatsResults() +{ + WCHAR fmt[200], buf[200]; + LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, fmt, _countof(fmt)); + wsprintfW(buf, fmt, m_cFiles, m_cFolders - (m_bMultifile ? 0 : 1)); + SetDlgItemTextW(m_hWndDirStatsDlg, m_bMultifile ? 14001 : 14027, buf); + + if (SH_FormatFileSizeWithBytes(&m_DirSize, buf, _countof(buf))) + SetDlgItemTextW(m_hWndDirStatsDlg, 14011, buf); + if (SH_FormatFileSizeWithBytes(&m_DirSizeOnDisc, buf, _countof(buf))) + SetDlgItemTextW(m_hWndDirStatsDlg, 14012, buf); +} + +void +CFileDefExt::InitDirStats(struct DIRTREESTATS *pStats) +{ + pStats->pDirCount = &m_cFolders; + pStats->pFileCount = &m_cFiles; + pStats->pTotVirtSize = &m_DirSize; + pStats->pTotPhysSize = &m_DirSizeOnDisc; + pStats->nTick = GetTickCount(); + pStats->fAttribSet = ~0ul; + pStats->fAttribAll = 0; + pStats->bDeepRecurse = FALSE; + pStats->bMultipleTypes = !m_bMultifile; // Only the Multifile page wants to know + pStats->szType[0] = UNICODE_NULL; +} + +static UINT +ProcessDirStatsItem(PCWSTR pszPath, DIRTREESTATS &Stats, WIN32_FIND_DATAW *pWFD) +{ + UINT fAttrib; + ULARGE_INTEGER nVirtSize, nPhysSize; + if (pWFD && (pWFD->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + fAttrib = pWFD->dwFileAttributes; + } + else + { + fAttrib = GetFileStats(pszPath, &nVirtSize, &nPhysSize); + if (fAttrib == INVALID_FILE_ATTRIBUTES) + return fAttrib; + } + + Stats.fAttribSet &= fAttrib; + Stats.fAttribAll |= fAttrib; + if (fAttrib & FILE_ATTRIBUTE_DIRECTORY) + { + (*Stats.pDirCount)++; + } + else + { + (*Stats.pFileCount)++; + Stats.pTotVirtSize->QuadPart += nVirtSize.QuadPart; + Stats.pTotPhysSize->QuadPart += nPhysSize.QuadPart; + } + + if (!Stats.bMultipleTypes) + { + SHFILEINFOW shfi; + if (!SHGetFileInfoW(pszPath, fAttrib, &shfi, sizeof(shfi), + SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES)) + Stats.bMultipleTypes = TRUE; + else if (!Stats.szType[0]) + wcscpy(Stats.szType, shfi.szTypeName); + else + Stats.bMultipleTypes = lstrcmpW(Stats.szType, shfi.szTypeName); + } + return fAttrib; +} + +BOOL +CFileDefExt::WalkDirTree(PCWSTR pszBase, struct DIRTREESTATS *pStats, WIN32_FIND_DATAW *pWFD) +{ + WIN32_FIND_DATAW wfd; + wfd.dwFileAttributes = ProcessDirStatsItem(pszBase, *pStats, pWFD); + if (wfd.dwFileAttributes == INVALID_FILE_ATTRIBUTES) + return FALSE; + if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + return TRUE; + + BOOL bSuccess = TRUE; + SIZE_T cch = lstrlenW(pszBase); + PWSTR pszFull = (PWSTR)SHAlloc((cch + MAX_PATH) * sizeof(*pszFull)); + if (!pszFull) + return FALSE; + PWSTR pszFile = pszFull + cch; + wcscpy(pszFull, pszBase); + wcscpy(pszFile++, L"\\*"); + HANDLE hFind = FindFirstFileW(pszFull, &wfd); + if (hFind != INVALID_HANDLE_VALUE) + { + for (; bSuccess && !IsDestroyed();) + { + UINT nTickNow = GetTickCount(); + if (nTickNow - pStats->nTick >= 500) + { + pStats->nTick = nTickNow; + SendMessageW(m_hWndDirStatsDlg, WM_UPDATEDIRSTATS, 0, 0); + } + + wcscpy(pszFile, wfd.cFileName); + if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + bSuccess = ProcessDirStatsItem(pszFull, *pStats, NULL); + } + else if (!PathIsDotOrDotDotW(wfd.cFileName)) + { + bSuccess = WalkDirTree(pszFull, pStats, &wfd); + pStats->bDeepRecurse |= bSuccess; + } + + if (!FindNextFileW(hFind, &wfd)) + break; + } + FindClose(hFind); + } + SHFree(pszFull); + return bSuccess; +} + +void +CFileDefExt::InitMultifilePageThread() +{ + DIRTREESTATS Stats; + InitDirStats(&Stats); + + // MSDN says CFSTR_SHELLIDLIST and SHGDN_FORPARSING must be supported so that is what we use + for (SIZE_T i = 0; i < m_cidl; ++i) + { + PIDLIST_ABSOLUTE pidl = ILCombine(m_pidlFolder, m_pidls[i]); + if (!pidl) + return; + PWSTR pszAbsPath; + HRESULT hr = SHELL_DisplayNameOf(NULL, pidl, SHGDN_FORPARSING, &pszAbsPath); + ILFree(pidl); + if (FAILED(hr)) + return; + BOOL bSuccess = WalkDirTree(pszAbsPath, &Stats, NULL); + SHFree(pszAbsPath); + if (!bSuccess) + return; + } + + UpdateDirStatsResults(); + if (Stats.bMultipleTypes) + LoadStringW(shell32_hInstance, IDS_MULTIPLETYPES, Stats.szType, _countof(Stats.szType)); + SetDlgItemTextW(m_hWndDirStatsDlg, 14005, Stats.szType); + + PWSTR pszDir = NULL; + HRESULT hr = E_FAIL; + if (!Stats.bDeepRecurse) + hr = SHELL_DisplayNameOf(NULL, m_pidlFolder, SHGDN_FORPARSING | SHGDN_FORADDRESSBAR, &pszDir); + if (SUCCEEDED(hr)) + { + SetDlgItemTextW(m_hWndDirStatsDlg, 14009, pszDir); + } + else + { + LoadStringW(shell32_hInstance, IDS_VARIOUSFOLDERS, Stats.szType, _countof(Stats.szType)); + SetDlgItemTextW(m_hWndDirStatsDlg, 14009, Stats.szType); + } + SHFree(pszDir); + + #define SetMultifileDlgFileAttr(attr, id) do \ + { \ + if (Stats.fAttribSet & (attr)) \ + CheckDlgButton(m_hWndDirStatsDlg, (id), BST_CHECKED); \ + else if (Stats.fAttribAll & (attr)) \ + CheckDlgButton(m_hWndDirStatsDlg, (id), BST_INDETERMINATE); \ + } while (0) + SetMultifileDlgFileAttr(FILE_ATTRIBUTE_READONLY, 14021); + SetMultifileDlgFileAttr(FILE_ATTRIBUTE_HIDDEN, 14022); + SetMultifileDlgFileAttr(FILE_ATTRIBUTE_ARCHIVE, 14023); + #undef SetMultifileDlgFileAttr +} + +DWORD CALLBACK +CFileDefExt::_InitializeMultifileThreadProc(LPVOID lpParameter) +{ + CFileDefExt *pThis = static_cast(lpParameter); + pThis->InitMultifilePageThread(); + return pThis->Release(); +} + +void +CFileDefExt::InitMultifilePage(HWND hwndDlg) +{ + m_hWndDirStatsDlg = hwndDlg; + HICON hIco = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_MULTIPLE_FILES)); + SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)hIco, 0); + + // We are lazy and just reuse the directory page so we must tweak some controls + HWND hCtrl = GetDlgItem(hwndDlg, 14001); + SetWindowLongPtrW(hCtrl, GWL_STYLE, GetWindowLongPtrW(GetDlgItem(hwndDlg, 14027), GWL_STYLE)); + SetWindowLongPtrW(hCtrl, GWL_EXSTYLE, 0); + SendMessageW(hCtrl, EM_SETREADONLY, TRUE, 0); + SetDlgItemTextW(hwndDlg, 14005, NULL); + + static const WORD idAttr[] = { 14021, 14022, 14023 }; + for (SIZE_T i = 0; i < _countof(idAttr); ++i) + { + hCtrl = GetDlgItem(hwndDlg, idAttr[i]); + SendMessageW(hCtrl, BM_SETSTYLE, BS_AUTO3STATE, TRUE); + EnableWindow(hCtrl, FALSE); + } + + static const WORD idUnused[] = { 14026, 14027, 14028, 14014, 14015 }; + for (SIZE_T i = 0; i < _countof(idUnused); ++i) + DestroyWindow(GetDlgItem(hwndDlg, idUnused[i])); + + if (!m_cidl) + return; + + AddRef(); + if (!SHCreateThread(_InitializeMultifileThreadProc, this, CTF_COINIT, NULL)) + Release(); +} + +/************************************************************************* + * + * CFileDefExt::MultifilePageProc + * + */ + +INT_PTR CALLBACK +CFileDefExt::MultifilePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + CFileDefExt *pFileDefExt = reinterpret_cast(GetWindowLongPtr(hwndDlg, DWLP_USER)); + switch (uMsg) + { + case WM_INITDIALOG: + { + LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam; + if (ppsp == NULL || !ppsp->lParam) + break; + pFileDefExt = reinterpret_cast(ppsp->lParam); + SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pFileDefExt); + pFileDefExt->InitMultifilePage(hwndDlg); + break; + } + case WM_DESTROY: + InterlockedIncrement(&pFileDefExt->m_Destroyed); + break; + case WM_UPDATEDIRSTATS: + pFileDefExt->UpdateDirStatsResults(); + break; + } + return FALSE; +} + /************************************************************************* * * CFileDefExt::InitVersionPage [Internal] @@ -957,12 +1235,6 @@ CFileDefExt::VersionPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar return TRUE; } break; - case WM_DESTROY: - break; - case PSM_QUERYSIBLINGS: - return FALSE; // continue - default: - break; } return FALSE; @@ -1216,7 +1488,7 @@ BOOL CFileDefExt::OnFolderCustApply(HWND hwndDlg) /*****************************************************************************/ CFileDefExt::CFileDefExt(): - m_bDir(FALSE), m_cFiles(0), m_cFolders(0) + m_bDir(FALSE), m_bMultifile(FALSE), m_cFiles(0), m_cFolders(0) { m_wszPath[0] = L'\0'; m_DirSize.QuadPart = 0ull; @@ -1230,7 +1502,8 @@ CFileDefExt::CFileDefExt(): CFileDefExt::~CFileDefExt() { - + _ILFreeaPidl(m_pidls, m_cidl); + ILFree(m_pidlFolder); } HRESULT WINAPI @@ -1245,6 +1518,19 @@ CFileDefExt::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDataObj, HKE if (!pDataObj) return E_FAIL; + int count = DataObject_GetHIDACount(pDataObj); + m_bMultifile = count > 1; + if (m_bMultifile) + { + CDataObjectHIDA cida(pDataObj); + if (SUCCEEDED(cida.hr())) + { + m_pidls = _ILCopyCidaToaPidl(&m_pidlFolder, cida); + if (m_pidls) + m_cidl = cida->cidl; + } + } + format.cfFormat = CF_HDROP; format.ptd = NULL; format.dwAspect = DVASPECT_CONTENT; @@ -1265,8 +1551,8 @@ CFileDefExt::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDataObj, HKE ReleaseStgMedium(&stgm); TRACE("File properties %ls\n", m_wszPath); - m_bDir = PathIsDirectoryW(m_wszPath) ? TRUE : FALSE; - if (!m_bDir) + m_bDir = !m_bMultifile && PathIsDirectoryW(m_wszPath); + if (!m_bDir && !m_bMultifile) m_VerInfo.Load(m_wszPath); return S_OK; @@ -1297,9 +1583,10 @@ HRESULT WINAPI CFileDefExt::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam) { HPROPSHEETPAGE hPage; - WORD wResId = m_bDir ? IDD_FOLDER_PROPERTIES : IDD_FILE_PROPERTIES; + WORD wResId = (m_bDir || m_bMultifile) ? IDD_FOLDER_PROPERTIES : IDD_FILE_PROPERTIES; + DLGPROC pfnFirstPage = m_bMultifile ? MultifilePageProc : GeneralPageProc; - hPage = SH_CreatePropertySheetPageEx(wResId, GeneralPageProc, (LPARAM)this, NULL, + hPage = SH_CreatePropertySheetPageEx(wResId, pfnFirstPage, (LPARAM)this, NULL, &PropSheetPageLifetimeCallback); HRESULT hr = AddPropSheetPage(hPage, pfnAddPage, lParam); if (FAILED_UNEXPECTEDLY(hr)) @@ -1307,6 +1594,9 @@ CFileDefExt::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam) else AddRef(); // For PropSheetPageLifetimeCallback + if (m_bMultifile) + return S_OK; + if (!m_bDir && GetFileVersionInfoSizeW(m_wszPath, NULL)) { hPage = SH_CreatePropertySheetPage(IDD_FILE_VERSION, @@ -1335,127 +1625,19 @@ CFileDefExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPAR return E_NOTIMPL; } -HRESULT WINAPI -CFileDefExt::SetSite(IUnknown *punk) +void +CFileDefExt::CountFolderAndFiles() { - UNIMPLEMENTED; - return E_NOTIMPL; + DIRTREESTATS Stats; + InitDirStats(&Stats); + WalkDirTree(m_wszPath, &Stats, NULL); + UpdateDirStatsResults(); } -HRESULT WINAPI -CFileDefExt::GetSite(REFIID iid, void **ppvSite) -{ - UNIMPLEMENTED; - return E_NOTIMPL; -} - -DWORD WINAPI +DWORD CALLBACK CFileDefExt::_CountFolderAndFilesThreadProc(LPVOID lpParameter) { - _CountFolderAndFilesData *data = static_cast<_CountFolderAndFilesData*>(lpParameter); - DWORD ticks = 0; - data->This->CountFolderAndFiles(data->hwndDlg, data->pwszBuf, &ticks); - - //Release the CFileDefExt and data object holds in the copying thread. - data->This->Release(); - HeapFree(GetProcessHeap(), 0, data->pwszBuf); - HeapFree(GetProcessHeap(), 0, data); - - return 0; -} - -BOOL -CFileDefExt::CountFolderAndFiles(HWND hwndDlg, LPCWSTR pwszBuf, DWORD *ticks) -{ - CString sBuf = pwszBuf; - sBuf += L"\\" ; - CString sSearch = sBuf; - sSearch += L"*" ; - CString sFileName; - - WIN32_FIND_DATAW wfd; - HANDLE hFind = FindFirstFileW(sSearch, &wfd); - if (hFind == INVALID_HANDLE_VALUE) - { - ERR("FindFirstFileW %ls failed\n", sSearch.GetString()); - return FALSE; - } - - BOOL root = FALSE; - if (*ticks == 0) { - *ticks = GetTickCount(); - root = TRUE; - } - - do - { - sFileName = sBuf; - sFileName += wfd.cFileName; - if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - /* Don't process "." and ".." items */ - if (!wcscmp(wfd.cFileName, L".") || !wcscmp(wfd.cFileName, L"..")) - continue; - - ++m_cFolders; - - CountFolderAndFiles(hwndDlg, sFileName, ticks); - } - else - { - m_cFiles++; - - ULARGE_INTEGER FileSize; - FileSize.u.LowPart = wfd.nFileSizeLow; - FileSize.u.HighPart = wfd.nFileSizeHigh; - m_DirSize.QuadPart += FileSize.QuadPart; - // Calculate size on disc - if (!GetPhysicalFileSize(sFileName.GetString(), &FileSize)) - ERR("GetPhysicalFileSize failed for %ls\n", sFileName.GetString()); - m_DirSizeOnDisc.QuadPart += FileSize.QuadPart; - } - if (GetTickCount() - *ticks > (DWORD) 300) - { - /* FIXME Using IsWindow is generally ill advised */ - if (IsWindow(hwndDlg)) - { - WCHAR wszBuf[100]; - - if (SH_FormatFileSizeWithBytes(&m_DirSize, wszBuf, _countof(wszBuf))) - SetDlgItemTextW(hwndDlg, 14011, wszBuf); - - if (SH_FormatFileSizeWithBytes(&m_DirSizeOnDisc, wszBuf, _countof(wszBuf))) - SetDlgItemTextW(hwndDlg, 14012, wszBuf); - - /* Display files and folders count */ - WCHAR wszFormat[100]; - LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, wszFormat, _countof(wszFormat)); - StringCchPrintfW(wszBuf, _countof(wszBuf), wszFormat, m_cFiles, m_cFolders); - SetDlgItemTextW(hwndDlg, 14027, wszBuf); - *ticks = GetTickCount(); - } - else - break; - } - } while(FindNextFileW(hFind, &wfd)); - - if (root && IsWindow(hwndDlg)) - { - WCHAR wszBuf[100]; - - if (SH_FormatFileSizeWithBytes(&m_DirSize, wszBuf, _countof(wszBuf))) - SetDlgItemTextW(hwndDlg, 14011, wszBuf); - - if (SH_FormatFileSizeWithBytes(&m_DirSizeOnDisc, wszBuf, _countof(wszBuf))) - SetDlgItemTextW(hwndDlg, 14012, wszBuf); - - /* Display files and folders count */ - WCHAR wszFormat[100]; - LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, wszFormat, _countof(wszFormat)); - StringCchPrintfW(wszBuf, _countof(wszBuf), wszFormat, m_cFiles, m_cFolders); - SetDlgItemTextW(hwndDlg, 14027, wszBuf); - } - - FindClose(hFind); - return TRUE; + CFileDefExt *pThis = static_cast(lpParameter); + pThis->CountFolderAndFiles(); + return pThis->Release(); } diff --git a/dll/win32/shell32/dialogs/filedefext.h b/dll/win32/shell32/dialogs/filedefext.h index 6ac57d35eb0..00f26bdbd64 100644 --- a/dll/win32/shell32/dialogs/filedefext.h +++ b/dll/win32/shell32/dialogs/filedefext.h @@ -59,7 +59,7 @@ class CFileDefExt : public IShellExtInit, public IContextMenu, public IShellPropSheetExt, - public IObjectWithSite + public CObjectWithSiteBase { private: VOID InitOpensWithField(HWND hwndDlg); @@ -72,21 +72,37 @@ private: BOOL AddVersionString(HWND hwndDlg, LPCWSTR pwszName); BOOL InitVersionPage(HWND hwndDlg); BOOL InitFolderCustomizePage(HWND hwndDlg); + void InitMultifilePage(HWND hwndDlg); + void InitMultifilePageThread(); + void CountFolderAndFiles(); static INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK VersionPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK FolderCustomizePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - BOOL CountFolderAndFiles(HWND hwndDlg, LPCWSTR pwszBuf, LPDWORD ticks); + static INT_PTR CALLBACK MultifilePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); WCHAR m_wszPath[MAX_PATH]; CFileVersionInfo m_VerInfo; - BOOL m_bDir; + BOOL m_bDir; + BOOL m_bMultifile; - DWORD m_cFiles; + LPITEMIDLIST m_pidlFolder = NULL; + LPITEMIDLIST *m_pidls = NULL; + UINT m_cidl = 0; + DWORD m_cFiles; DWORD m_cFolders; ULARGE_INTEGER m_DirSize; ULARGE_INTEGER m_DirSizeOnDisc; + enum { WM_UPDATEDIRSTATS = WM_APP }; + HWND m_hWndDirStatsDlg; + void InitDirStats(struct DIRTREESTATS *pStats); + BOOL WalkDirTree(PCWSTR pszPath, struct DIRTREESTATS *pStats, WIN32_FIND_DATAW *pWFD); + void UpdateDirStatsResults(); + + LONG volatile m_Destroyed = 0; + BOOL IsDestroyed() const { return m_Destroyed; } static DWORD WINAPI _CountFolderAndFilesThreadProc(LPVOID lpParameter); + static DWORD WINAPI _InitializeMultifileThreadProc(LPVOID lpParameter); // FolderCustomize WCHAR m_szFolderIconPath[MAX_PATH]; @@ -116,10 +132,6 @@ public: STDMETHOD(AddPages)(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam) override; STDMETHOD(ReplacePage)(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam) override; - // IObjectWithSite - STDMETHOD(SetSite)(IUnknown *punk) override; - STDMETHOD(GetSite)(REFIID iid, void **ppvSite) override; - DECLARE_REGISTRY_RESOURCEID(IDR_FILEDEFEXT) DECLARE_NOT_AGGREGATABLE(CFileDefExt) diff --git a/dll/win32/shell32/dialogs/item_prop.cpp b/dll/win32/shell32/dialogs/item_prop.cpp index 5d00526a55a..22d47c34329 100644 --- a/dll/win32/shell32/dialogs/item_prop.cpp +++ b/dll/win32/shell32/dialogs/item_prop.cpp @@ -176,8 +176,7 @@ SHELL32_ShowFilesystemItemPropertiesDialogAsync(IDataObject *pDO) pClsid = &CLSID_ShellFileDefExt; InitFunc = FSFolderItemPropDialogInitCallback; } - ShellPropSheetDialog Dialog; - return Dialog.ShowAsync(pClsid, pDO, InitFunc, InitString); + return ShellPropSheetDialog().ShowAsync(pClsid, pDO, InitFunc, InitString); } HRESULT @@ -185,11 +184,7 @@ SHELL32_ShowFilesystemItemsPropertiesDialogAsync(HWND hOwner, IDataObject *pDO) { if (DataObject_GetHIDACount(pDO) == 1) return SHELL32_ShowFilesystemItemPropertiesDialogAsync(pDO); - - ERR("SHMultiFileProperties is not implemented yet\n"); - HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); - SHELL_ErrorBox(hOwner, hr); - return hr; // TODO: return SHMultiFileProperties(pDO, 0); + return SHMultiFileProperties(pDO, 0); } HRESULT @@ -197,8 +192,7 @@ SHELL32_ShowShellExtensionProperties(const CLSID *pClsid, IDataObject *pDO) { WCHAR ClassBuf[6 + 38 + 1] = L"CLSID\\"; StringFromGUID2(*pClsid, ClassBuf + 6, 38 + 1); - ShellPropSheetDialog Dialog; - return Dialog.ShowAsync(NULL, pDO, ClassPropDialogInitCallback, ClassBuf); + return ShellPropSheetDialog().ShowAsync(NULL, pDO, ClassPropDialogInitCallback, ClassBuf); } HRESULT @@ -220,3 +214,16 @@ SHELL_ShowItemIDListProperties(LPCITEMIDLIST pidl) }; return ShellExecuteExA(&sei) ? S_OK : HResultFromWin32(GetLastError()); } + +/* + * SHMultiFileProperties [SHELL32.716] + */ +EXTERN_C HRESULT +WINAPI +SHMultiFileProperties(IDataObject *pDataObject, DWORD dwFlags) +{ + if (DataObject_GetHIDACount(pDataObject) == 1) + return SHELL32_ShowFilesystemItemPropertiesDialogAsync(pDataObject); + + return ShellPropSheetDialog().ShowAsync(&CLSID_ShellFileDefExt, pDataObject, NULL, NULL); +} diff --git a/dll/win32/shell32/folders/CDesktopFolder.cpp b/dll/win32/shell32/folders/CDesktopFolder.cpp index 27e2dafd08b..abc6f7a1f04 100644 --- a/dll/win32/shell32/folders/CDesktopFolder.cpp +++ b/dll/win32/shell32/folders/CDesktopFolder.cpp @@ -1049,7 +1049,15 @@ HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IData enum { IDC_PROPERTIES }; if (uMsg == DFM_INVOKECOMMAND && wParam == (pdtobj ? DFM_CMD_PROPERTIES : IDC_PROPERTIES)) { - return SHELL_ExecuteControlPanelCPL(hwndOwner, L"desk.cpl") ? S_OK : E_FAIL; + if (pdtobj) + { + PIDLIST_ABSOLUTE pidl = SHELL_DataObject_ILCloneFullItem(pdtobj, 0); + BOOL bIsSelf = _ILIsDesktop(pidl); // Context menu on Desktop item in the shell tree? + ILFree(pidl); + if (!bIsSelf) + return SHELL32_ShowPropertiesDialog(pdtobj); // File selection + } + return SHELL_ExecuteControlPanelCPL(hwndOwner, L"desk.cpl") ? S_OK : E_FAIL; // Background } else if (uMsg == DFM_MERGECONTEXTMENU && !pdtobj) // Add Properties item when called for directory background { diff --git a/dll/win32/shell32/lang/bg-BG.rc b/dll/win32/shell32/lang/bg-BG.rc index 4bcc76ca435..fb2c4d8b213 100644 --- a/dll/win32/shell32/lang/bg-BG.rc +++ b/dll/win32/shell32/lang/bg-BG.rc @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Разпечатване" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u файла, %u папки" + IDS_PRINTERS "Печатачи" IDS_FONTS "Шрифтове" IDS_INSTALLNEWFONT "Слагане на нов шрифт..." diff --git a/dll/win32/shell32/lang/ca-ES.rc b/dll/win32/shell32/lang/ca-ES.rc index 020071e5a02..eeaf96c0f11 100644 --- a/dll/win32/shell32/lang/ca-ES.rc +++ b/dll/win32/shell32/lang/ca-ES.rc @@ -228,7 +228,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 16, 7, 32, 32, WS_VISIBLE EDITTEXT 14001, 58, 9, 170, 14, ES_LEFT - LTEXT "Type of file:", 14004, 8, 40, 55, 10 + LTEXT "Type:", 14004, 8, 40, 55, 10 CONTROL "Folder", 14005, "edit", ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL, 58, 40, 170, 10 LTEXT "", -1, 8, 31, 221, 1, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE LTEXT "Location:", 14008, 8, 56, 55, 10 @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Print" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Files, %u Folders" + IDS_PRINTERS "Printers" IDS_FONTS "Fonts" IDS_INSTALLNEWFONT "Install New Font..." diff --git a/dll/win32/shell32/lang/cs-CZ.rc b/dll/win32/shell32/lang/cs-CZ.rc index 2566b76e742..60965130a15 100644 --- a/dll/win32/shell32/lang/cs-CZ.rc +++ b/dll/win32/shell32/lang/cs-CZ.rc @@ -984,7 +984,10 @@ BEGIN IDS_PRINT_VERB "Tisknout" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u souborů, %u složek" + IDS_PRINTERS "Tiskárny" IDS_FONTS "Písma" IDS_INSTALLNEWFONT "Nainstalovat nové písmo..." diff --git a/dll/win32/shell32/lang/da-DK.rc b/dll/win32/shell32/lang/da-DK.rc index f10d9f27935..e63fbc0c060 100644 --- a/dll/win32/shell32/lang/da-DK.rc +++ b/dll/win32/shell32/lang/da-DK.rc @@ -235,7 +235,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 16, 7, 32, 32, WS_VISIBLE EDITTEXT 14001, 58, 9, 170, 14, ES_LEFT - LTEXT "Type of file:", 14004, 8, 40, 55, 10 + LTEXT "Type:", 14004, 8, 40, 55, 10 CONTROL "Folder", 14005, "edit", ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL, 58, 40, 170, 10 LTEXT "", -1, 8, 31, 221, 1, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE LTEXT "Location:", 14008, 8, 56, 55, 10 @@ -983,7 +983,10 @@ BEGIN IDS_PRINT_VERB "Print" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Files, %u Folders" + IDS_PRINTERS "Printers" IDS_FONTS "Fonts" IDS_INSTALLNEWFONT "Install New Font..." diff --git a/dll/win32/shell32/lang/de-DE.rc b/dll/win32/shell32/lang/de-DE.rc index 065d250bdb4..fd18c16cf46 100644 --- a/dll/win32/shell32/lang/de-DE.rc +++ b/dll/win32/shell32/lang/de-DE.rc @@ -977,7 +977,10 @@ BEGIN IDS_PRINT_VERB "Drucken" IDS_CMD_VERB "Cmd hier" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Dateien, %u Ordner" + IDS_PRINTERS "Drucker" IDS_FONTS "Schriftarten" IDS_INSTALLNEWFONT "Neue Schriftart installieren..." diff --git a/dll/win32/shell32/lang/el-GR.rc b/dll/win32/shell32/lang/el-GR.rc index 5a3f7d1c50d..a5a6cf11f05 100644 --- a/dll/win32/shell32/lang/el-GR.rc +++ b/dll/win32/shell32/lang/el-GR.rc @@ -228,7 +228,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 16, 7, 32, 32, WS_VISIBLE EDITTEXT 14001, 58, 9, 170, 14, ES_LEFT - LTEXT "Type of file:", 14004, 8, 40, 55, 10 + LTEXT "Type:", 14004, 8, 40, 55, 10 CONTROL "Folder", 14005, "edit", ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL, 58, 40, 170, 10 LTEXT "", -1, 8, 31, 221, 1, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE LTEXT "Location:", 14008, 8, 56, 55, 10 @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Print" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Files, %u Folders" + IDS_PRINTERS "Printers" IDS_FONTS "Fonts" IDS_INSTALLNEWFONT "Install New Font..." diff --git a/dll/win32/shell32/lang/en-GB.rc b/dll/win32/shell32/lang/en-GB.rc index 64d99f652f4..a49781c9b17 100644 --- a/dll/win32/shell32/lang/en-GB.rc +++ b/dll/win32/shell32/lang/en-GB.rc @@ -228,7 +228,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 16, 7, 32, 32, WS_VISIBLE EDITTEXT 14001, 58, 9, 170, 14, ES_LEFT - LTEXT "Type of file:", 14004, 8, 40, 55, 10 + LTEXT "Type:", 14004, 8, 40, 55, 10 CONTROL "Folder", 14005, "edit", ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL, 58, 40, 170, 10 LTEXT "", -1, 8, 31, 221, 1, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE LTEXT "Location:", 14008, 8, 56, 55, 10 @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Print" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Files, %u Folders" + IDS_PRINTERS "Printers" IDS_FONTS "Fonts" IDS_INSTALLNEWFONT "Install New Font..." diff --git a/dll/win32/shell32/lang/en-US.rc b/dll/win32/shell32/lang/en-US.rc index a61104b2177..c8d683d1ff7 100644 --- a/dll/win32/shell32/lang/en-US.rc +++ b/dll/win32/shell32/lang/en-US.rc @@ -228,7 +228,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 16, 7, 32, 32, WS_VISIBLE EDITTEXT 14001, 58, 9, 170, 14, ES_LEFT - LTEXT "Type of file:", 14004, 8, 40, 55, 10 //FIXME: Reminder to myself when overhauling that dlg: In this line we will just keep "Type:" (nothing after it) and in the next line we do keep the type in the CONTROL name. Is shown! Harmonize all the left-column 55 width IDD_FOLDER_PROPERTIES (which is too large) with the all 45 width in IDD_FILE_PROPERTIES. The 170 width in right-column is non-negotiable! Increase both dlgs heights to restore vertical arrangement of the Attributes like on 2k3sp2. Make all the Attributes 70 wide each. That will also unbreak the "Advanced"-buttons. + LTEXT "Type:", 14004, 8, 40, 55, 10 //FIXME: Reminder to myself when overhauling that dlg: In the next line we do keep the type in the CONTROL name. Is shown! Harmonize all the left-column 55 width IDD_FOLDER_PROPERTIES (which is too large) with the all 45 width in IDD_FILE_PROPERTIES. The 170 width in right-column is non-negotiable! Increase both dlgs heights to restore vertical arrangement of the Attributes like on 2k3sp2. Make all the Attributes 70 wide each. That will also unbreak the "Advanced"-buttons. CONTROL "Folder", 14005, "edit", ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL, 58, 40, 170, 10 LTEXT "", -1, 8, 31, 221, 1, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE LTEXT "Location:", 14008, 8, 56, 55, 10 @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Print" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Files, %u Folders" + IDS_PRINTERS "Printers" IDS_FONTS "Fonts" IDS_INSTALLNEWFONT "Install New Font..." diff --git a/dll/win32/shell32/lang/es-ES.rc b/dll/win32/shell32/lang/es-ES.rc index cdd0232adad..ac8534a44ff 100644 --- a/dll/win32/shell32/lang/es-ES.rc +++ b/dll/win32/shell32/lang/es-ES.rc @@ -985,7 +985,10 @@ BEGIN IDS_PRINT_VERB "Imprimir" IDS_CMD_VERB "Abrir en Línea de Comandos" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u archivos, %u carpetas" + IDS_PRINTERS "Impresoras" IDS_FONTS "Fuentes" IDS_INSTALLNEWFONT "Instalar fuente..." diff --git a/dll/win32/shell32/lang/et-EE.rc b/dll/win32/shell32/lang/et-EE.rc index 12983b93194..da10e978118 100644 --- a/dll/win32/shell32/lang/et-EE.rc +++ b/dll/win32/shell32/lang/et-EE.rc @@ -983,7 +983,10 @@ BEGIN IDS_PRINT_VERB "Prindi" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Faili, %u Kausta" + IDS_PRINTERS "Printerid" IDS_FONTS "Fondid" IDS_INSTALLNEWFONT "Paigalda uus font..." diff --git a/dll/win32/shell32/lang/eu-ES.rc b/dll/win32/shell32/lang/eu-ES.rc index faafc9e7323..aa1b310bf8f 100644 --- a/dll/win32/shell32/lang/eu-ES.rc +++ b/dll/win32/shell32/lang/eu-ES.rc @@ -981,7 +981,10 @@ BEGIN IDS_PRINT_VERB "Inprimatu" IDS_CMD_VERB "Ireki terminalan" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u fitxategiak, %u karpetak" + IDS_PRINTERS "Imprimagailuak" IDS_FONTS "Letra-tipo" IDS_INSTALLNEWFONT "Letra-tipo instalatu..." diff --git a/dll/win32/shell32/lang/fi-FI.rc b/dll/win32/shell32/lang/fi-FI.rc index 327dccdb80e..b04c72097ed 100644 --- a/dll/win32/shell32/lang/fi-FI.rc +++ b/dll/win32/shell32/lang/fi-FI.rc @@ -228,7 +228,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 16, 7, 32, 32, WS_VISIBLE EDITTEXT 14001, 58, 9, 170, 14, ES_LEFT - LTEXT "Type of file:", 14004, 8, 40, 55, 10 + LTEXT "Type:", 14004, 8, 40, 55, 10 CONTROL "Folder", 14005, "edit", ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL, 58, 40, 170, 10 LTEXT "", -1, 8, 31, 221, 1, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE LTEXT "Location:", 14008, 8, 56, 55, 10 @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Print" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Files, %u Folders" + IDS_PRINTERS "Printers" IDS_FONTS "Fonts" IDS_INSTALLNEWFONT "Install New Font..." diff --git a/dll/win32/shell32/lang/fr-FR.rc b/dll/win32/shell32/lang/fr-FR.rc index c7e91097ee8..0fc1efca5bc 100644 --- a/dll/win32/shell32/lang/fr-FR.rc +++ b/dll/win32/shell32/lang/fr-FR.rc @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Imprimer" IDS_CMD_VERB "Ouvrir l'invite de commandes" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u fichiers, %u répertoires" + IDS_PRINTERS "Imprimantes" IDS_FONTS "Polices" IDS_INSTALLNEWFONT "Installer une nouvelle police..." diff --git a/dll/win32/shell32/lang/he-IL.rc b/dll/win32/shell32/lang/he-IL.rc index bbf80e9447b..816adc73f70 100644 --- a/dll/win32/shell32/lang/he-IL.rc +++ b/dll/win32/shell32/lang/he-IL.rc @@ -983,7 +983,10 @@ BEGIN IDS_PRINT_VERB "הדפס" IDS_CMD_VERB "פתח בשורת הפקודה" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u קבצים, %u תיקיות" + IDS_PRINTERS "מדפסות" IDS_FONTS "גופנים" IDS_INSTALLNEWFONT "התקנת גופן חדש..." diff --git a/dll/win32/shell32/lang/hi-IN.rc b/dll/win32/shell32/lang/hi-IN.rc index 49bc606745a..71a06744664 100644 --- a/dll/win32/shell32/lang/hi-IN.rc +++ b/dll/win32/shell32/lang/hi-IN.rc @@ -978,7 +978,10 @@ BEGIN IDS_PRINT_VERB "प्रिंट" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u फ़ाइलें, %u फ़ोल्डर" + IDS_PRINTERS "प्रिंटर" IDS_FONTS "फोंट्स" IDS_INSTALLNEWFONT "नया फ़ॉन्ट इन्स्टॉल करें..." diff --git a/dll/win32/shell32/lang/hu-HU.rc b/dll/win32/shell32/lang/hu-HU.rc index 45ab97696b9..0b227bcc705 100644 --- a/dll/win32/shell32/lang/hu-HU.rc +++ b/dll/win32/shell32/lang/hu-HU.rc @@ -975,7 +975,10 @@ BEGIN IDS_PRINT_VERB "Nyomtatás" IDS_CMD_VERB "Parancssor indítása innen" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u fájl, %u mappa" + IDS_PRINTERS "Nyomtatók" IDS_FONTS "Betűtípusok" IDS_INSTALLNEWFONT "Új betűtípus telepítése..." diff --git a/dll/win32/shell32/lang/id-ID.rc b/dll/win32/shell32/lang/id-ID.rc index 5173e7f0158..c1d6af21458 100644 --- a/dll/win32/shell32/lang/id-ID.rc +++ b/dll/win32/shell32/lang/id-ID.rc @@ -973,7 +973,10 @@ BEGIN IDS_PRINT_VERB "Cetak" IDS_CMD_VERB "Perintah Cepat di sini" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Berkas, %u Folder" + IDS_PRINTERS "Printer" IDS_FONTS "Fon" IDS_INSTALLNEWFONT "Memasang fon baru..." diff --git a/dll/win32/shell32/lang/it-IT.rc b/dll/win32/shell32/lang/it-IT.rc index 0b47c540fdb..3bcea579093 100644 --- a/dll/win32/shell32/lang/it-IT.rc +++ b/dll/win32/shell32/lang/it-IT.rc @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Stampa" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u File, %u Cartelle" + IDS_PRINTERS "Stampanti" IDS_FONTS "Font" IDS_INSTALLNEWFONT "Installazione nuovi Font..." diff --git a/dll/win32/shell32/lang/ja-JP.rc b/dll/win32/shell32/lang/ja-JP.rc index 5edadbe3534..e8c4a7f35fc 100644 --- a/dll/win32/shell32/lang/ja-JP.rc +++ b/dll/win32/shell32/lang/ja-JP.rc @@ -973,7 +973,10 @@ BEGIN IDS_PRINT_VERB "印刷" IDS_CMD_VERB "ここでコマンドプロンプトを開く" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u 個のファイル、 %u 個のフォルダ" + IDS_PRINTERS "プリンタ" IDS_FONTS "フォント" IDS_INSTALLNEWFONT "新しいフォントのインストール..." diff --git a/dll/win32/shell32/lang/ko-KR.rc b/dll/win32/shell32/lang/ko-KR.rc index d534ab6f98b..6a57df9c051 100644 --- a/dll/win32/shell32/lang/ko-KR.rc +++ b/dll/win32/shell32/lang/ko-KR.rc @@ -983,7 +983,10 @@ BEGIN IDS_PRINT_VERB "Print" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Files, %u Folders" + IDS_PRINTERS "Printers" IDS_FONTS "Fonts" IDS_INSTALLNEWFONT "Install New Font..." diff --git a/dll/win32/shell32/lang/nl-NL.rc b/dll/win32/shell32/lang/nl-NL.rc index fa829d20331..0a6b17ee808 100644 --- a/dll/win32/shell32/lang/nl-NL.rc +++ b/dll/win32/shell32/lang/nl-NL.rc @@ -228,7 +228,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 16, 7, 32, 32, WS_VISIBLE EDITTEXT 14001, 58, 9, 170, 14, ES_LEFT - LTEXT "Type of file:", 14004, 8, 40, 55, 10 + LTEXT "Type:", 14004, 8, 40, 55, 10 CONTROL "Folder", 14005, "edit", ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL, 58, 40, 170, 10 LTEXT "", -1, 8, 31, 221, 1, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE LTEXT "Location:", 14008, 8, 56, 55, 10 @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Print" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Files, %u Folders" + IDS_PRINTERS "Printers" IDS_FONTS "Fonts" IDS_INSTALLNEWFONT "Install New Font..." diff --git a/dll/win32/shell32/lang/no-NO.rc b/dll/win32/shell32/lang/no-NO.rc index e345401bd33..24332e51ddc 100644 --- a/dll/win32/shell32/lang/no-NO.rc +++ b/dll/win32/shell32/lang/no-NO.rc @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Skriv ut" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u filer, %u mapper" + IDS_PRINTERS "Skrivere" IDS_FONTS "Skrifttyper" IDS_INSTALLNEWFONT "Installere nye skrifttyper..." diff --git a/dll/win32/shell32/lang/pl-PL.rc b/dll/win32/shell32/lang/pl-PL.rc index b8a2d20c299..c4c88f590b0 100644 --- a/dll/win32/shell32/lang/pl-PL.rc +++ b/dll/win32/shell32/lang/pl-PL.rc @@ -985,7 +985,10 @@ BEGIN IDS_PRINT_VERB "Drukuj" IDS_CMD_VERB "&Otwórz wiersz polecenia tutaj" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Plików, %u Katalogów" + IDS_PRINTERS "Drukarki" IDS_FONTS "Czcionki" IDS_INSTALLNEWFONT "Zainstaluj nową czcionkę..." diff --git a/dll/win32/shell32/lang/pt-BR.rc b/dll/win32/shell32/lang/pt-BR.rc index 1677d173efb..c6a0ae49c16 100644 --- a/dll/win32/shell32/lang/pt-BR.rc +++ b/dll/win32/shell32/lang/pt-BR.rc @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Imprimir" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Arquivos, %u Pastas" + IDS_PRINTERS "Impressoras" IDS_FONTS "Fontes" IDS_INSTALLNEWFONT "Instalar Nova Fonte..." diff --git a/dll/win32/shell32/lang/pt-PT.rc b/dll/win32/shell32/lang/pt-PT.rc index 400c9a6b09b..1bee457b425 100644 --- a/dll/win32/shell32/lang/pt-PT.rc +++ b/dll/win32/shell32/lang/pt-PT.rc @@ -985,7 +985,10 @@ BEGIN IDS_PRINT_VERB "Imprimir" IDS_CMD_VERB "Linha de Comandos aqui" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Ficheiros, %u Pastas" + IDS_PRINTERS "Impressoras" IDS_FONTS "Tipos de letra" IDS_INSTALLNEWFONT "Instalar novo tipo de letra..." diff --git a/dll/win32/shell32/lang/ro-RO.rc b/dll/win32/shell32/lang/ro-RO.rc index 94b92ab418b..da4782b0f78 100644 --- a/dll/win32/shell32/lang/ro-RO.rc +++ b/dll/win32/shell32/lang/ro-RO.rc @@ -984,7 +984,10 @@ BEGIN IDS_PRINT_VERB "Imprimare" IDS_CMD_VERB "Deschidere Panou de control aici" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u fişiere, %u foldere" + IDS_PRINTERS "Imprimante" IDS_FONTS "Fonturi" IDS_INSTALLNEWFONT "Instalare font nou…" diff --git a/dll/win32/shell32/lang/ru-RU.rc b/dll/win32/shell32/lang/ru-RU.rc index ff6ba439152..fdfa67c9933 100644 --- a/dll/win32/shell32/lang/ru-RU.rc +++ b/dll/win32/shell32/lang/ru-RU.rc @@ -985,7 +985,10 @@ BEGIN IDS_PRINT_VERB "Печать" IDS_CMD_VERB "Командная строка" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u файлов, %u папок" + IDS_PRINTERS "Принтеры" IDS_FONTS "Шрифты" IDS_INSTALLNEWFONT "Установить новый шрифт..." diff --git a/dll/win32/shell32/lang/sk-SK.rc b/dll/win32/shell32/lang/sk-SK.rc index f4da6a1a075..b947d67ddc6 100644 --- a/dll/win32/shell32/lang/sk-SK.rc +++ b/dll/win32/shell32/lang/sk-SK.rc @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Tlačiť" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "súbory: %u, priečinky: %u" + IDS_PRINTERS "Tlačiarne" IDS_FONTS "Písma" IDS_INSTALLNEWFONT "&Nainštalovať nové písmo..." diff --git a/dll/win32/shell32/lang/sl-SI.rc b/dll/win32/shell32/lang/sl-SI.rc index 69e1f20ff3c..ed2793d2bed 100644 --- a/dll/win32/shell32/lang/sl-SI.rc +++ b/dll/win32/shell32/lang/sl-SI.rc @@ -228,7 +228,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 16, 7, 32, 32, WS_VISIBLE EDITTEXT 14001, 58, 9, 170, 14, ES_LEFT - LTEXT "Type of file:", 14004, 8, 40, 55, 10 + LTEXT "Type:", 14004, 8, 40, 55, 10 CONTROL "Folder", 14005, "edit", ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL, 58, 40, 170, 10 LTEXT "", -1, 8, 31, 221, 1, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE LTEXT "Location:", 14008, 8, 56, 55, 10 @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Print" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Files, %u Folders" + IDS_PRINTERS "Printers" IDS_FONTS "Fonts" IDS_INSTALLNEWFONT "Install New Font..." diff --git a/dll/win32/shell32/lang/sq-AL.rc b/dll/win32/shell32/lang/sq-AL.rc index 607cd85954e..1bdb1905d31 100644 --- a/dll/win32/shell32/lang/sq-AL.rc +++ b/dll/win32/shell32/lang/sq-AL.rc @@ -983,7 +983,10 @@ BEGIN IDS_PRINT_VERB "Printo" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Dokumenta, %u Dosje" + IDS_PRINTERS "Printera" IDS_FONTS "Fonte" IDS_INSTALLNEWFONT "Instalo Fonte të Ri..." diff --git a/dll/win32/shell32/lang/sv-SE.rc b/dll/win32/shell32/lang/sv-SE.rc index c591c343c78..cbcec524bde 100644 --- a/dll/win32/shell32/lang/sv-SE.rc +++ b/dll/win32/shell32/lang/sv-SE.rc @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Skriv ut" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u filer, %u mappar" + IDS_PRINTERS "Skrivare" IDS_FONTS "Teckensnitt" IDS_INSTALLNEWFONT "Installera nytt teckensnitt..." diff --git a/dll/win32/shell32/lang/tr-TR.rc b/dll/win32/shell32/lang/tr-TR.rc index 29ca66b604d..ee13a19512e 100644 --- a/dll/win32/shell32/lang/tr-TR.rc +++ b/dll/win32/shell32/lang/tr-TR.rc @@ -985,7 +985,10 @@ BEGIN IDS_PRINT_VERB "Yazdır" IDS_CMD_VERB "Burada komut istemi aç" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u Dosya, %u Dizin" + IDS_PRINTERS "Yazıcılar" IDS_FONTS "Yazı Tipleri" IDS_INSTALLNEWFONT "Yeni Yazı Tipi Yükle..." diff --git a/dll/win32/shell32/lang/uk-UA.rc b/dll/win32/shell32/lang/uk-UA.rc index fc1b333f9ff..1a429098fbf 100644 --- a/dll/win32/shell32/lang/uk-UA.rc +++ b/dll/win32/shell32/lang/uk-UA.rc @@ -976,7 +976,10 @@ BEGIN IDS_PRINT_VERB "Друк" IDS_CMD_VERB "Command Prompt here" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u файлів, %u папок" + IDS_PRINTERS "Принтери" IDS_FONTS "Шрифти" IDS_INSTALLNEWFONT "Інсталювати новий шрифт..." diff --git a/dll/win32/shell32/lang/zh-CN.rc b/dll/win32/shell32/lang/zh-CN.rc index 35b7d97f35c..659db1f4cb7 100644 --- a/dll/win32/shell32/lang/zh-CN.rc +++ b/dll/win32/shell32/lang/zh-CN.rc @@ -986,7 +986,10 @@ BEGIN IDS_PRINT_VERB "打印" IDS_CMD_VERB "在此打开命令提示符" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u 个文件,%u 个文件夹" + IDS_PRINTERS "打印机" IDS_FONTS "字体" IDS_INSTALLNEWFONT "安装新字体..." diff --git a/dll/win32/shell32/lang/zh-HK.rc b/dll/win32/shell32/lang/zh-HK.rc index c491f825cd6..f3aac193e67 100644 --- a/dll/win32/shell32/lang/zh-HK.rc +++ b/dll/win32/shell32/lang/zh-HK.rc @@ -984,7 +984,10 @@ BEGIN IDS_PRINT_VERB "列印" IDS_CMD_VERB "在這裡開啟命令提示字元" + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u 個檔案,%u 個檔案夾" + IDS_PRINTERS "印表機" IDS_FONTS "字型" IDS_INSTALLNEWFONT "安裝新字型..." diff --git a/dll/win32/shell32/lang/zh-TW.rc b/dll/win32/shell32/lang/zh-TW.rc index a31bc153d4d..b5f3d26cf30 100644 --- a/dll/win32/shell32/lang/zh-TW.rc +++ b/dll/win32/shell32/lang/zh-TW.rc @@ -985,7 +985,11 @@ BEGIN IDS_PRINT_VERB "列印" IDS_CMD_VERB "在這裡開啟命令提示字元" + + IDS_MULTIPLETYPES "Multiple Types" + IDS_VARIOUSFOLDERS "Various Folders" IDS_FILE_FOLDER "%u 個檔案,%u 個資料夾" + IDS_PRINTERS "印表機" IDS_FONTS "字型" IDS_INSTALLNEWFONT "安裝新字型..." diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h index eea446156a6..bca0bef06e6 100644 --- a/dll/win32/shell32/precomp.h +++ b/dll/win32/shell32/precomp.h @@ -255,6 +255,13 @@ SHELL_GetUIObjectOfAbsoluteItem( _In_ PCIDLIST_ABSOLUTE pidl, _In_ REFIID riid, _Out_ void **ppvObj); +HRESULT +SHELL_DisplayNameOf( + _In_opt_ IShellFolder *psf, + _In_ LPCITEMIDLIST pidl, + _In_opt_ UINT Flags, + _Out_ PWSTR *ppStr); + DWORD SHGetAttributes(_In_ IShellFolder *psf, _In_ LPCITEMIDLIST pidl, _In_ DWORD dwAttributes); HRESULT SHELL_GetIDListTarget(_In_ LPCITEMIDLIST pidl, _Out_ PIDLIST_ABSOLUTE *ppidl); diff --git a/dll/win32/shell32/shresdef.h b/dll/win32/shell32/shresdef.h index ceafd0df542..1ff82cac77e 100644 --- a/dll/win32/shell32/shresdef.h +++ b/dll/win32/shell32/shresdef.h @@ -262,6 +262,10 @@ #define IDS_SHORTCUT_RUN_MIN 4168 #define IDS_SHORTCUT_RUN_MAX 4169 +/* FS property sheet */ +#define IDS_MULTIPLETYPES 8705 +#define IDS_VARIOUSFOLDERS 8709 + #define IDS_MENU_EMPTY 34561 /* Note: those strings are referenced from the registry */ diff --git a/dll/win32/shell32/stubs.cpp b/dll/win32/shell32/stubs.cpp index 1cdee237d44..28f6faa9aa3 100644 --- a/dll/win32/shell32/stubs.cpp +++ b/dll/win32/shell32/stubs.cpp @@ -84,30 +84,6 @@ SHParseDarwinIDFromCacheW(LPCWSTR lpUnknown1, LPWSTR lpUnknown2) return E_FAIL; } -/* - * Unimplemented - */ -EXTERN_C HRESULT -WINAPI -SHMultiFileProperties(IDataObject *pDataObject, DWORD dwFlags) -{ - FIXME("SHMultiFileProperties() stub\n"); - - // Temporary workaround to display a property sheet if possible - if (DataObject_GetHIDACount(pDataObject) == 1) - return SHELL32_ShowPropertiesDialog(pDataObject); - - if (pDataObject) - { - HWND hWnd; - if (FAILED(IUnknown_GetWindow(pDataObject, &hWnd))) // Will probably not work but we have no other option - hWnd = NULL; - SHELL_ErrorBox(hWnd, HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)); - } - - return E_FAIL; -} - /* * Unimplemented */ diff --git a/dll/win32/shell32/utils.cpp b/dll/win32/shell32/utils.cpp index e5f8cee9411..8f9e000b08b 100644 --- a/dll/win32/shell32/utils.cpp +++ b/dll/win32/shell32/utils.cpp @@ -402,6 +402,29 @@ SHELL_GetUIObjectOfAbsoluteItem( return hr; } +HRESULT +SHELL_DisplayNameOf( + _In_opt_ IShellFolder *psf, + _In_ LPCITEMIDLIST pidl, + _In_opt_ UINT Flags, + _Out_ PWSTR *ppStr) +{ + HRESULT hr; + CComPtr psfRoot; + if (!psf) + { + PCUITEMID_CHILD pidlChild; + hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfRoot), &pidlChild); + if (FAILED(hr)) + return hr; + psf = psfRoot; + pidl = pidlChild; + } + STRRET sr; + hr = psf->GetDisplayNameOf((PCUITEMID_CHILD)pidl, Flags, &sr); + return SUCCEEDED(hr) ? StrRetToStrW(&sr, pidl, ppStr) : hr; +} + /*********************************************************************** * DisplayNameOfW [SHELL32.757] (Vista+) */ diff --git a/dll/win32/shell32/wine/pidl.c b/dll/win32/shell32/wine/pidl.c index d927cd48c9c..afeeef8a02f 100644 --- a/dll/win32/shell32/wine/pidl.c +++ b/dll/win32/shell32/wine/pidl.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "pidl.h" #include "shell32_main.h" @@ -2606,11 +2607,9 @@ DWORD _ILGetFileAttributes(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize) */ void _ILFreeaPidl(LPITEMIDLIST * apidl, UINT cidl) { - UINT i; - if (apidl) { - for (i = 0; i < cidl; i++) + for (UINT i = 0; i < cidl; i++) SHFree(apidl[i]); SHFree(apidl); } @@ -2623,17 +2622,21 @@ void _ILFreeaPidl(LPITEMIDLIST * apidl, UINT cidl) */ PITEMID_CHILD* _ILCopyaPidl(PCUITEMID_CHILD_ARRAY apidlsrc, UINT cidl) { - UINT i; PITEMID_CHILD *apidldest; if (!apidlsrc) return NULL; apidldest = SHAlloc(cidl * sizeof(PITEMID_CHILD)); - - for (i = 0; i < cidl; i++) - apidldest[i] = ILClone(apidlsrc[i]); - + for (UINT i = 0; i < cidl; i++) + { + PITEMID_CHILD clone = ILClone(apidlsrc[i]); + if ((apidldest[i] = clone) == NULL) + { + _ILFreeaPidl(apidldest, i); + return NULL; + } + } return apidldest; } @@ -2645,17 +2648,28 @@ PITEMID_CHILD* _ILCopyaPidl(PCUITEMID_CHILD_ARRAY apidlsrc, UINT cidl) LPITEMIDLIST* _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, const CIDA * cida) { UINT i; - LPITEMIDLIST *dst; - - dst = SHAlloc(cida->cidl * sizeof(LPITEMIDLIST)); + LPITEMIDLIST *dst = SHAlloc(cida->cidl * sizeof(LPITEMIDLIST)); if (!dst) return NULL; - if (pidl) - *pidl = ILClone((LPCITEMIDLIST)(&((const BYTE*)cida)[cida->aoffset[0]])); - for (i = 0; i < cida->cidl; i++) - dst[i] = ILClone((LPCITEMIDLIST)(&((const BYTE*)cida)[cida->aoffset[i + 1]])); + { + PITEMID_CHILD clone = ILClone(HIDA_GetPIDLItem(cida, i)); + if ((dst[i] = clone) == NULL) + { + _ILFreeaPidl(dst, i); + return NULL; + } + } + if (pidl) + { + *pidl = ILClone(HIDA_GetPIDLFolder(cida)); + if (!*pidl) + { + _ILFreeaPidl(dst, cida->cidl); + return NULL; + } + } return dst; } diff --git a/sdk/include/reactos/shellutils.h b/sdk/include/reactos/shellutils.h index 10aebceeada..9ceb08cc374 100644 --- a/sdk/include/reactos/shellutils.h +++ b/sdk/include/reactos/shellutils.h @@ -652,9 +652,6 @@ public: return m_pUnkSite ? m_pUnkSite->QueryInterface(riid, ppvSite) : E_FAIL; } }; - - - #endif /* __cplusplus */ #define S_LESSTHAN 0xffff