Skip to content

Commit b6562a6

Browse files
authored
[SHELL32] DefView statusbar item file size fix in recycler and UNC (reactos#7732)
- Display item sizes inside \\ UNC paths. - Don't display anything in the location pane inside the Recycle Bin (CORE-20005). - Don't display the size and location panes in My Computer - Don't update the location pane on simple item selection changes. CORE-20005
1 parent c7eba0c commit b6562a6

File tree

6 files changed

+95
-73
lines changed

6 files changed

+95
-73
lines changed

dll/win32/shell32/CDefView.cpp

Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ class CDefView :
273273
CComPtr<IContextMenu> m_pFileMenu;
274274

275275
BOOL m_isEditing;
276-
BOOL m_isParentFolderSpecial;
276+
signed char m_SpecialFolder;
277+
bool m_isFullStatusBar;
277278
bool m_ScheduledStatusbarUpdate;
278279
bool m_HasCutItems;
279280

@@ -294,6 +295,12 @@ class CDefView :
294295
void _DoCopyToMoveToFolder(BOOL bCopy);
295296
BOOL IsDesktop() const { return m_FolderSettings.fFlags & FWF_DESKTOP; }
296297

298+
inline BOOL IsSpecialFolder(int &csidl) const
299+
{
300+
csidl = m_SpecialFolder;
301+
return m_SpecialFolder >= 0;
302+
}
303+
297304
public:
298305
CDefView();
299306
~CDefView();
@@ -302,6 +309,7 @@ class CDefView :
302309
HRESULT OnDefaultCommand();
303310
HRESULT OnStateChange(UINT uFlags);
304311
void UpdateStatusbar();
312+
void UpdateStatusbarLocation();
305313
void CheckToolbar();
306314
BOOL CreateList();
307315
void UpdateListColors();
@@ -601,7 +609,8 @@ CDefView::CDefView() :
601609
m_iDragOverItem(0),
602610
m_cScrollDelay(0),
603611
m_isEditing(FALSE),
604-
m_isParentFolderSpecial(FALSE),
612+
m_SpecialFolder(-1),
613+
m_isFullStatusBar(true),
605614
m_ScheduledStatusbarUpdate(false),
606615
m_HasCutItems(false),
607616
m_Destroyed(FALSE)
@@ -721,8 +730,8 @@ void CDefView::CheckToolbar()
721730

722731
void CDefView::UpdateStatusbar()
723732
{
724-
WCHAR szFormat[MAX_PATH] = {0};
725-
WCHAR szPartText[MAX_PATH] = {0};
733+
WCHAR szFormat[MAX_PATH];
734+
WCHAR szPartText[MAX_PATH];
726735
UINT cSelectedItems;
727736

728737
if (!m_ListView)
@@ -744,11 +753,10 @@ void CDefView::UpdateStatusbar()
744753
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 0, (LPARAM)szPartText, &lResult);
745754

746755
// Don't bother with the extra processing if we only have one StatusBar part
747-
if (!m_isParentFolderSpecial)
756+
if (m_isFullStatusBar)
748757
{
749758
UINT64 uTotalFileSize = 0;
750759
WORD uFileFlags = LVNI_ALL;
751-
LPARAM pIcon = NULL;
752760
INT nItem = -1;
753761
bool bIsOnlyFoldersSelected = true;
754762

@@ -773,25 +781,11 @@ void CDefView::UpdateStatusbar()
773781
// Don't show the file size text if there is 0 bytes in the folder
774782
// OR we only have folders selected
775783
if ((cSelectedItems && !bIsOnlyFoldersSelected) || uTotalFileSize)
776-
{
777784
StrFormatByteSizeW(uTotalFileSize, szPartText, _countof(szPartText));
778-
}
779785
else
780-
{
781786
*szPartText = 0;
782-
}
783787

784788
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1, (LPARAM)szPartText, &lResult);
785-
786-
// If we are in a Recycle Bin then show no text for the location part
787-
if (!_ILIsBitBucket(m_pidlParent))
788-
{
789-
LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText));
790-
pIcon = (LPARAM)m_hMyComputerIcon;
791-
}
792-
793-
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETICON, 2, pIcon, &lResult);
794-
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 2, (LPARAM)szPartText, &lResult);
795789
}
796790

797791
SFGAOF att = 0;
@@ -806,6 +800,32 @@ void CDefView::UpdateStatusbar()
806800
m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_ENABLEBUTTON, FCIDM_SHVIEW_MOVETO, (att & SFGAO_CANMOVE) != 0, &lResult);
807801
}
808802

803+
void CDefView::UpdateStatusbarLocation()
804+
{
805+
LRESULT lResult;
806+
LPARAM pIcon = NULL;
807+
WCHAR szPartText[MAX_PATH];
808+
*szPartText = 0;
809+
if (m_isFullStatusBar)
810+
{
811+
// If we are in a Recycle Bin then show no text for the location part
812+
int csidl;
813+
if (!IsSpecialFolder(csidl) || (csidl != CSIDL_NETWORK && csidl != CSIDL_BITBUCKET))
814+
{
815+
LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText));
816+
pIcon = (LPARAM)m_hMyComputerIcon;
817+
}
818+
/*else if (csidl == CSIDL_NETWORK) // TODO: Figure out the type of share (My Computer/Local Intranet/Internet?)
819+
{
820+
ImageList_GetIconSize(ListView_GetImageList(m_ListView, LVSIL_SMALL), &x, &y);
821+
pIcon = (LPARAM)LoadImage(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_MY_NETWORK_PLACES),
822+
IMAGE_ICON, x, y, LR_SHARED);
823+
}*/
824+
}
825+
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETICON, 2, pIcon, &lResult);
826+
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 2, (LPARAM)szPartText, &lResult);
827+
}
828+
809829
LRESULT CDefView::OnUpdateStatusbar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
810830
{
811831
m_ScheduledStatusbarUpdate = false;
@@ -1555,7 +1575,7 @@ HRESULT CDefView::FillList(BOOL IsRefreshCommand)
15551575
// copy the items into the array
15561576
while((S_OK == pEnumIDList->Next(1, &pidl, &dwFetched)) && dwFetched)
15571577
{
1558-
if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
1578+
if (DPA_AppendPtr(hdpa, pidl) == -1)
15591579
{
15601580
SHFree(pidl);
15611581
}
@@ -1605,6 +1625,9 @@ HRESULT CDefView::FillList(BOOL IsRefreshCommand)
16051625
m_ListView.InvalidateRect(NULL, TRUE);
16061626
}
16071627

1628+
if (IsRefreshCommand)
1629+
UpdateStatusbarLocation();
1630+
16081631
_DoFolderViewCB(SFVM_LISTREFRESHED, 0, 0);
16091632

16101633
return S_OK;
@@ -1793,22 +1816,27 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
17931816

17941817
m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW));
17951818

1796-
BOOL bPreviousParentSpecial = m_isParentFolderSpecial;
1797-
1798-
// A folder is special if it is the Desktop folder,
1799-
// a network folder, or a Control Panel folder
1800-
m_isParentFolderSpecial = IsDesktop() || _ILIsNetHood(m_pidlParent)
1801-
|| _ILIsControlPanel(ILFindLastID(m_pidlParent));
1802-
1803-
// Only force StatusBar part refresh if the state
1804-
// changed from the previous folder
1805-
if (bPreviousParentSpecial != m_isParentFolderSpecial)
1819+
int bForceFullStatusBar = false;
1820+
BOOL bIsFileSystem = SHGetAttributes(NULL, m_pidlParent, SFGAO_FILESYSTEM) & SFGAO_FILESYSTEM;
1821+
m_SpecialFolder = bIsFileSystem ? -1 : 0x7f; // FS folder or "generic" CSIDL
1822+
if (_ILIsDesktop(m_pidlParent))
18061823
{
1807-
// This handles changing StatusBar parts
1808-
_ForceStatusBarResize();
1824+
m_SpecialFolder = CSIDL_DESKTOP;
18091825
}
1810-
1826+
else if (IsEqualPersistClassID(ppf2, CLSID_RecycleBin))
1827+
{
1828+
m_SpecialFolder = bForceFullStatusBar = CSIDL_BITBUCKET;
1829+
}
1830+
else if (bIsFileSystem)
1831+
{
1832+
CComHeapPtr<ITEMIDLIST> pidlNet(SHCloneSpecialIDList(NULL, CSIDL_NETWORK, FALSE));
1833+
if (ILIsParent(pidlNet, m_pidlParent, FALSE) && ILGetSize(pidlNet) < ILGetSize(m_pidlParent))
1834+
m_SpecialFolder = CSIDL_NETWORK;
1835+
}
1836+
m_isFullStatusBar = bIsFileSystem || bForceFullStatusBar;
1837+
_ForceStatusBarResize(); // This handles changing StatusBar parts
18111838
UpdateStatusbar();
1839+
UpdateStatusbarLocation();
18121840

18131841
return S_OK;
18141842
}
@@ -4474,7 +4502,7 @@ void CDefView::_HandleStatusBarResize(int nWidth)
44744502
{
44754503
LRESULT lResult;
44764504

4477-
if (m_isParentFolderSpecial)
4505+
if (!m_isFullStatusBar)
44784506
{
44794507
int nPartArray[] = {-1};
44804508
m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray), (LPARAM)nPartArray, &lResult);

dll/win32/shell32/folders/CDesktopFolder.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ static const CLSID* IsRegItem(PCUITEMID_CHILD pidl)
5454
return NULL;
5555
}
5656

57+
static bool IsRegItem(PCUITEMID_CHILD pidl, REFCLSID clsid)
58+
{
59+
const CLSID *pClass = IsRegItem(pidl);
60+
return pClass && *pClass == clsid;
61+
}
62+
5763
static inline void MarkAsCommonItem(LPITEMIDLIST pidl)
5864
{
5965
ASSERT(_ILGetFSType(pidl) & PT_FS);
@@ -708,12 +714,12 @@ HRESULT WINAPI CDesktopFolder::GetAttributesOf(
708714
/* TODO: always add SFGAO_CANLINK */
709715
for (UINT i = 0; i < cidl; ++i)
710716
{
711-
pdump(*apidl);
712-
if (_ILIsDesktop(*apidl))
717+
pdump(apidl[i]);
718+
if (_ILIsDesktop(apidl[i]))
713719
*rgfInOut &= dwDesktopAttributes;
714720
else if (_ILIsMyComputer(apidl[i]))
715721
*rgfInOut &= dwMyComputerAttributes;
716-
else if (_ILIsNetHood(apidl[i]))
722+
else if (IsRegItem(apidl[i], CLSID_NetworkPlaces))
717723
*rgfInOut &= dwMyNetPlacesAttributes;
718724
else if (_ILIsFolderOrFile(apidl[i]) || _ILIsSpecialFolder(apidl[i]))
719725
{

dll/win32/shell32/folders/CDrivesFolder.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ static const CLSID* IsRegItem(PCUITEMID_CHILD pidl)
7878
return NULL;
7979
}
8080

81+
static bool IsRegItem(PCUITEMID_CHILD pidl, REFCLSID clsid)
82+
{
83+
const CLSID *pClass = IsRegItem(pidl);
84+
return pClass && *pClass == clsid;
85+
}
86+
8187
static INT8 GetDriveNumber(PCUITEMID_CHILD pidl)
8288
{
8389
if (!_ILIsDrive(pidl))
@@ -99,6 +105,7 @@ template<class T> static T* GetDrivePath(PCUITEMID_CHILD pidl, T *Path)
99105
return Path;
100106
}
101107

108+
102109
BOOL _ILGetDriveType(LPCITEMIDLIST pidl)
103110
{
104111
WCHAR szDrive[8];
@@ -586,7 +593,7 @@ static const shvheader MyComputerSFHeader[] = {
586593

587594
static const DWORD dwComputerAttributes =
588595
SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
589-
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
596+
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
590597
static const DWORD dwControlPanelAttributes =
591598
SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK;
592599
static const DWORD dwDriveAttributes =
@@ -875,7 +882,6 @@ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY a
875882
if (*rgfInOut == 0)
876883
*rgfInOut = ~0;
877884

878-
/* FIXME: always add SFGAO_CANLINK */
879885
if(cidl == 0)
880886
*rgfInOut &= dwComputerAttributes;
881887
else
@@ -889,7 +895,7 @@ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY a
889895
if (_ILGetDriveType(apidl[i]) == DRIVE_CDROM)
890896
*rgfInOut &= ~SFGAO_CANRENAME; // CD-ROM drive cannot rename
891897
}
892-
else if (_ILIsControlPanel(apidl[i]))
898+
else if (IsRegItem(apidl[i], CLSID_ControlPanel))
893899
{
894900
*rgfInOut &= dwControlPanelAttributes;
895901
}

dll/win32/shell32/utils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ SHELL_ErrorBox(CMINVOKECOMMANDINFO &cmi, UINT Error)
2424
}
2525
#endif
2626

27+
static inline BOOL
28+
IsEqualPersistClassID(IPersist *pPersist, REFCLSID clsid)
29+
{
30+
CLSID temp;
31+
return pPersist && SUCCEEDED(pPersist->GetClassID(&temp)) && IsEqualCLSID(clsid, temp);
32+
}
33+
2734
static inline BOOL
2835
RegValueExists(HKEY hKey, LPCWSTR Name)
2936
{

dll/win32/shell32/wine/pidl.c

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,30 +1763,29 @@ LPITEMIDLIST _ILCreateDesktop(void)
17631763
LPITEMIDLIST _ILCreateMyComputer(void)
17641764
{
17651765
TRACE("()\n");
1766-
return _ILCreateGuid(PT_GUID, &CLSID_MyComputer);
1766+
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyComputer);
17671767
}
17681768

17691769
LPITEMIDLIST _ILCreateMyDocuments(void)
17701770
{
17711771
TRACE("()\n");
1772-
return _ILCreateGuid(PT_GUID, &CLSID_MyDocuments);
1772+
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyDocuments);
17731773
}
17741774

17751775
LPITEMIDLIST _ILCreateIExplore(void)
17761776
{
17771777
TRACE("()\n");
1778-
return _ILCreateGuid(PT_GUID, &CLSID_Internet);
1778+
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_Internet);
17791779
}
17801780

17811781
LPITEMIDLIST _ILCreateControlPanel(void)
17821782
{
1783-
LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL;
1783+
LPITEMIDLIST parent = _ILCreateMyComputer(), ret = NULL;
17841784

17851785
TRACE("()\n");
17861786
if (parent)
17871787
{
1788-
LPITEMIDLIST cpl = _ILCreateGuid(PT_SHELLEXT, &CLSID_ControlPanel);
1789-
1788+
LPITEMIDLIST cpl = _ILCreateGuid(PT_COMPUTER_REGITEM, &CLSID_ControlPanel);
17901789
if (cpl)
17911790
{
17921791
ret = ILCombine(parent, cpl);
@@ -1827,13 +1826,13 @@ LPITEMIDLIST _ILCreatePrinters(void)
18271826
LPITEMIDLIST _ILCreateNetwork(void)
18281827
{
18291828
TRACE("()\n");
1830-
return _ILCreateGuid(PT_GUID, &CLSID_NetworkPlaces);
1829+
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_NetworkPlaces);
18311830
}
18321831

18331832
LPITEMIDLIST _ILCreateBitBucket(void)
18341833
{
18351834
TRACE("()\n");
1836-
return _ILCreateGuid(PT_GUID, &CLSID_RecycleBin);
1835+
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_RecycleBin);
18371836
}
18381837

18391838
LPITEMIDLIST _ILCreateAdminTools(void)
@@ -2060,28 +2059,6 @@ BOOL _ILIsMyDocuments(LPCITEMIDLIST pidl)
20602059
return FALSE;
20612060
}
20622061

2063-
BOOL _ILIsNetHood(LPCITEMIDLIST pidl)
2064-
{
2065-
IID *iid = _ILGetGUIDPointer(pidl);
2066-
2067-
TRACE("(%p)\n", pidl);
2068-
2069-
if (iid)
2070-
return IsEqualIID(iid, &CLSID_NetworkPlaces);
2071-
return FALSE;
2072-
}
2073-
2074-
BOOL _ILIsControlPanel(LPCITEMIDLIST pidl)
2075-
{
2076-
IID *iid = _ILGetGUIDPointer(pidl);
2077-
2078-
TRACE("(%p)\n", pidl);
2079-
2080-
if (iid)
2081-
return IsEqualIID(iid, &CLSID_ControlPanel);
2082-
return FALSE;
2083-
}
2084-
20852062
BOOL _ILIsMyComputer(LPCITEMIDLIST pidl)
20862063
{
20872064
REFIID iid = _ILGetGUIDPointer(pidl);

dll/win32/shell32/wine/pidl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,6 @@ BOOL _ILIsMyComputer (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;
248248
#ifdef __REACTOS__
249249
BOOL _ILIsMyDocuments (LPCITEMIDLIST pidl);
250250
BOOL _ILIsBitBucket (LPCITEMIDLIST pidl);
251-
BOOL _ILIsNetHood (LPCITEMIDLIST pidl);
252-
BOOL _ILIsControlPanel (LPCITEMIDLIST pidl);
253251
#define _ILIsFolderOrFile _ILGetFSType
254252
#endif
255253
BOOL _ILIsDrive (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;

0 commit comments

Comments
 (0)