diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp index 66b8fb8dc70..8b4e7536522 100644 --- a/dll/win32/shell32/CDefView.cpp +++ b/dll/win32/shell32/CDefView.cpp @@ -273,7 +273,8 @@ private: CComPtr m_pFileMenu; BOOL m_isEditing; - BOOL m_isParentFolderSpecial; + signed char m_SpecialFolder; + bool m_isFullStatusBar; bool m_ScheduledStatusbarUpdate; bool m_HasCutItems; @@ -294,6 +295,12 @@ private: void _DoCopyToMoveToFolder(BOOL bCopy); BOOL IsDesktop() const { return m_FolderSettings.fFlags & FWF_DESKTOP; } + inline BOOL IsSpecialFolder(int &csidl) const + { + csidl = m_SpecialFolder; + return m_SpecialFolder >= 0; + } + public: CDefView(); ~CDefView(); @@ -302,6 +309,7 @@ public: HRESULT OnDefaultCommand(); HRESULT OnStateChange(UINT uFlags); void UpdateStatusbar(); + void UpdateStatusbarLocation(); void CheckToolbar(); BOOL CreateList(); void UpdateListColors(); @@ -601,7 +609,8 @@ CDefView::CDefView() : m_iDragOverItem(0), m_cScrollDelay(0), m_isEditing(FALSE), - m_isParentFolderSpecial(FALSE), + m_SpecialFolder(-1), + m_isFullStatusBar(true), m_ScheduledStatusbarUpdate(false), m_HasCutItems(false), m_Destroyed(FALSE) @@ -721,8 +730,8 @@ void CDefView::CheckToolbar() void CDefView::UpdateStatusbar() { - WCHAR szFormat[MAX_PATH] = {0}; - WCHAR szPartText[MAX_PATH] = {0}; + WCHAR szFormat[MAX_PATH]; + WCHAR szPartText[MAX_PATH]; UINT cSelectedItems; if (!m_ListView) @@ -744,11 +753,10 @@ void CDefView::UpdateStatusbar() m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 0, (LPARAM)szPartText, &lResult); // Don't bother with the extra processing if we only have one StatusBar part - if (!m_isParentFolderSpecial) + if (m_isFullStatusBar) { UINT64 uTotalFileSize = 0; WORD uFileFlags = LVNI_ALL; - LPARAM pIcon = NULL; INT nItem = -1; bool bIsOnlyFoldersSelected = true; @@ -773,25 +781,11 @@ void CDefView::UpdateStatusbar() // Don't show the file size text if there is 0 bytes in the folder // OR we only have folders selected if ((cSelectedItems && !bIsOnlyFoldersSelected) || uTotalFileSize) - { StrFormatByteSizeW(uTotalFileSize, szPartText, _countof(szPartText)); - } else - { *szPartText = 0; - } m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1, (LPARAM)szPartText, &lResult); - - // If we are in a Recycle Bin then show no text for the location part - if (!_ILIsBitBucket(m_pidlParent)) - { - LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText)); - pIcon = (LPARAM)m_hMyComputerIcon; - } - - m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETICON, 2, pIcon, &lResult); - m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 2, (LPARAM)szPartText, &lResult); } SFGAOF att = 0; @@ -806,6 +800,32 @@ void CDefView::UpdateStatusbar() m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_ENABLEBUTTON, FCIDM_SHVIEW_MOVETO, (att & SFGAO_CANMOVE) != 0, &lResult); } +void CDefView::UpdateStatusbarLocation() +{ + LRESULT lResult; + LPARAM pIcon = NULL; + WCHAR szPartText[MAX_PATH]; + *szPartText = 0; + if (m_isFullStatusBar) + { + // If we are in a Recycle Bin then show no text for the location part + int csidl; + if (!IsSpecialFolder(csidl) || (csidl != CSIDL_NETWORK && csidl != CSIDL_BITBUCKET)) + { + LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText)); + pIcon = (LPARAM)m_hMyComputerIcon; + } + /*else if (csidl == CSIDL_NETWORK) // TODO: Figure out the type of share (My Computer/Local Intranet/Internet?) + { + ImageList_GetIconSize(ListView_GetImageList(m_ListView, LVSIL_SMALL), &x, &y); + pIcon = (LPARAM)LoadImage(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_MY_NETWORK_PLACES), + IMAGE_ICON, x, y, LR_SHARED); + }*/ + } + m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETICON, 2, pIcon, &lResult); + m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 2, (LPARAM)szPartText, &lResult); +} + LRESULT CDefView::OnUpdateStatusbar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { m_ScheduledStatusbarUpdate = false; @@ -1555,7 +1575,7 @@ HRESULT CDefView::FillList(BOOL IsRefreshCommand) // copy the items into the array while((S_OK == pEnumIDList->Next(1, &pidl, &dwFetched)) && dwFetched) { - if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1) + if (DPA_AppendPtr(hdpa, pidl) == -1) { SHFree(pidl); } @@ -1605,6 +1625,9 @@ HRESULT CDefView::FillList(BOOL IsRefreshCommand) m_ListView.InvalidateRect(NULL, TRUE); } + if (IsRefreshCommand) + UpdateStatusbarLocation(); + _DoFolderViewCB(SFVM_LISTREFRESHED, 0, 0); return S_OK; @@ -1793,22 +1816,27 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW)); - BOOL bPreviousParentSpecial = m_isParentFolderSpecial; - - // A folder is special if it is the Desktop folder, - // a network folder, or a Control Panel folder - m_isParentFolderSpecial = IsDesktop() || _ILIsNetHood(m_pidlParent) - || _ILIsControlPanel(ILFindLastID(m_pidlParent)); - - // Only force StatusBar part refresh if the state - // changed from the previous folder - if (bPreviousParentSpecial != m_isParentFolderSpecial) + int bForceFullStatusBar = false; + BOOL bIsFileSystem = SHGetAttributes(NULL, m_pidlParent, SFGAO_FILESYSTEM) & SFGAO_FILESYSTEM; + m_SpecialFolder = bIsFileSystem ? -1 : 0x7f; // FS folder or "generic" CSIDL + if (_ILIsDesktop(m_pidlParent)) { - // This handles changing StatusBar parts - _ForceStatusBarResize(); + m_SpecialFolder = CSIDL_DESKTOP; } - + else if (IsEqualPersistClassID(ppf2, CLSID_RecycleBin)) + { + m_SpecialFolder = bForceFullStatusBar = CSIDL_BITBUCKET; + } + else if (bIsFileSystem) + { + CComHeapPtr pidlNet(SHCloneSpecialIDList(NULL, CSIDL_NETWORK, FALSE)); + if (ILIsParent(pidlNet, m_pidlParent, FALSE) && ILGetSize(pidlNet) < ILGetSize(m_pidlParent)) + m_SpecialFolder = CSIDL_NETWORK; + } + m_isFullStatusBar = bIsFileSystem || bForceFullStatusBar; + _ForceStatusBarResize(); // This handles changing StatusBar parts UpdateStatusbar(); + UpdateStatusbarLocation(); return S_OK; } @@ -4474,7 +4502,7 @@ void CDefView::_HandleStatusBarResize(int nWidth) { LRESULT lResult; - if (m_isParentFolderSpecial) + if (!m_isFullStatusBar) { int nPartArray[] = {-1}; m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray), (LPARAM)nPartArray, &lResult); diff --git a/dll/win32/shell32/folders/CDesktopFolder.cpp b/dll/win32/shell32/folders/CDesktopFolder.cpp index 626fe007ef7..3999df2d481 100644 --- a/dll/win32/shell32/folders/CDesktopFolder.cpp +++ b/dll/win32/shell32/folders/CDesktopFolder.cpp @@ -54,6 +54,12 @@ static const CLSID* IsRegItem(PCUITEMID_CHILD pidl) return NULL; } +static bool IsRegItem(PCUITEMID_CHILD pidl, REFCLSID clsid) +{ + const CLSID *pClass = IsRegItem(pidl); + return pClass && *pClass == clsid; +} + static inline void MarkAsCommonItem(LPITEMIDLIST pidl) { ASSERT(_ILGetFSType(pidl) & PT_FS); @@ -708,12 +714,12 @@ HRESULT WINAPI CDesktopFolder::GetAttributesOf( /* TODO: always add SFGAO_CANLINK */ for (UINT i = 0; i < cidl; ++i) { - pdump(*apidl); - if (_ILIsDesktop(*apidl)) + pdump(apidl[i]); + if (_ILIsDesktop(apidl[i])) *rgfInOut &= dwDesktopAttributes; else if (_ILIsMyComputer(apidl[i])) *rgfInOut &= dwMyComputerAttributes; - else if (_ILIsNetHood(apidl[i])) + else if (IsRegItem(apidl[i], CLSID_NetworkPlaces)) *rgfInOut &= dwMyNetPlacesAttributes; else if (_ILIsFolderOrFile(apidl[i]) || _ILIsSpecialFolder(apidl[i])) { diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp b/dll/win32/shell32/folders/CDrivesFolder.cpp index 9d82c5ce8e9..00d932e596e 100644 --- a/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -78,6 +78,12 @@ static const CLSID* IsRegItem(PCUITEMID_CHILD pidl) return NULL; } +static bool IsRegItem(PCUITEMID_CHILD pidl, REFCLSID clsid) +{ + const CLSID *pClass = IsRegItem(pidl); + return pClass && *pClass == clsid; +} + static INT8 GetDriveNumber(PCUITEMID_CHILD pidl) { if (!_ILIsDrive(pidl)) @@ -99,6 +105,7 @@ template static T* GetDrivePath(PCUITEMID_CHILD pidl, T *Path) return Path; } + BOOL _ILGetDriveType(LPCITEMIDLIST pidl) { WCHAR szDrive[8]; @@ -586,7 +593,7 @@ static const shvheader MyComputerSFHeader[] = { static const DWORD dwComputerAttributes = SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | - SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER; + SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK; static const DWORD dwControlPanelAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK; static const DWORD dwDriveAttributes = @@ -875,7 +882,6 @@ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY a if (*rgfInOut == 0) *rgfInOut = ~0; - /* FIXME: always add SFGAO_CANLINK */ if(cidl == 0) *rgfInOut &= dwComputerAttributes; else @@ -889,7 +895,7 @@ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY a if (_ILGetDriveType(apidl[i]) == DRIVE_CDROM) *rgfInOut &= ~SFGAO_CANRENAME; // CD-ROM drive cannot rename } - else if (_ILIsControlPanel(apidl[i])) + else if (IsRegItem(apidl[i], CLSID_ControlPanel)) { *rgfInOut &= dwControlPanelAttributes; } diff --git a/dll/win32/shell32/utils.h b/dll/win32/shell32/utils.h index f583cb65741..4f13d541f8f 100644 --- a/dll/win32/shell32/utils.h +++ b/dll/win32/shell32/utils.h @@ -24,6 +24,13 @@ SHELL_ErrorBox(CMINVOKECOMMANDINFO &cmi, UINT Error) } #endif +static inline BOOL +IsEqualPersistClassID(IPersist *pPersist, REFCLSID clsid) +{ + CLSID temp; + return pPersist && SUCCEEDED(pPersist->GetClassID(&temp)) && IsEqualCLSID(clsid, temp); +} + static inline BOOL RegValueExists(HKEY hKey, LPCWSTR Name) { diff --git a/dll/win32/shell32/wine/pidl.c b/dll/win32/shell32/wine/pidl.c index 1417192f8a8..43511ca40f1 100644 --- a/dll/win32/shell32/wine/pidl.c +++ b/dll/win32/shell32/wine/pidl.c @@ -1763,30 +1763,29 @@ LPITEMIDLIST _ILCreateDesktop(void) LPITEMIDLIST _ILCreateMyComputer(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_MyComputer); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyComputer); } LPITEMIDLIST _ILCreateMyDocuments(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_MyDocuments); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyDocuments); } LPITEMIDLIST _ILCreateIExplore(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_Internet); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_Internet); } LPITEMIDLIST _ILCreateControlPanel(void) { - LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL; + LPITEMIDLIST parent = _ILCreateMyComputer(), ret = NULL; TRACE("()\n"); if (parent) { - LPITEMIDLIST cpl = _ILCreateGuid(PT_SHELLEXT, &CLSID_ControlPanel); - + LPITEMIDLIST cpl = _ILCreateGuid(PT_COMPUTER_REGITEM, &CLSID_ControlPanel); if (cpl) { ret = ILCombine(parent, cpl); @@ -1827,13 +1826,13 @@ LPITEMIDLIST _ILCreatePrinters(void) LPITEMIDLIST _ILCreateNetwork(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_NetworkPlaces); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_NetworkPlaces); } LPITEMIDLIST _ILCreateBitBucket(void) { TRACE("()\n"); - return _ILCreateGuid(PT_GUID, &CLSID_RecycleBin); + return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_RecycleBin); } LPITEMIDLIST _ILCreateAdminTools(void) @@ -2060,28 +2059,6 @@ BOOL _ILIsMyDocuments(LPCITEMIDLIST pidl) return FALSE; } -BOOL _ILIsNetHood(LPCITEMIDLIST pidl) -{ - IID *iid = _ILGetGUIDPointer(pidl); - - TRACE("(%p)\n", pidl); - - if (iid) - return IsEqualIID(iid, &CLSID_NetworkPlaces); - return FALSE; -} - -BOOL _ILIsControlPanel(LPCITEMIDLIST pidl) -{ - IID *iid = _ILGetGUIDPointer(pidl); - - TRACE("(%p)\n", pidl); - - if (iid) - return IsEqualIID(iid, &CLSID_ControlPanel); - return FALSE; -} - BOOL _ILIsMyComputer(LPCITEMIDLIST pidl) { REFIID iid = _ILGetGUIDPointer(pidl); diff --git a/dll/win32/shell32/wine/pidl.h b/dll/win32/shell32/wine/pidl.h index 7680b38645c..e5cb36b2b2d 100644 --- a/dll/win32/shell32/wine/pidl.h +++ b/dll/win32/shell32/wine/pidl.h @@ -248,8 +248,6 @@ BOOL _ILIsMyComputer (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN; #ifdef __REACTOS__ BOOL _ILIsMyDocuments (LPCITEMIDLIST pidl); BOOL _ILIsBitBucket (LPCITEMIDLIST pidl); -BOOL _ILIsNetHood (LPCITEMIDLIST pidl); -BOOL _ILIsControlPanel (LPCITEMIDLIST pidl); #define _ILIsFolderOrFile _ILGetFSType #endif BOOL _ILIsDrive (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;