https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3e2df36561ee2360dcbb0…
commit 3e2df36561ee2360dcbb08f59aa9837ec479351f
Author: Russell Johnson <russell.johnson(a)superdark.net>
AuthorDate: Tue May 3 06:52:23 2022 -0700
Commit: GitHub <noreply(a)github.com>
CommitDate: Tue May 3 16:52:23 2022 +0300
[SHELL32] Add multiple status bar parts to the file browser (#4401)
The file browser now has a status bar like Windows Server 2003 does.
This includes the sizes of the files, as well as the location.
In certain folders (Network, Desktop, etc.) the status bar is hidden.
Currently it does not handle this in the same way as Windows Shell does,
however it's a good first step to make it work properly.
CORE-17603
Signed-off-by: Russell Johnson <russell.johnson(a)superdark.net>
Reviewed-by: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
Reviewed-by: Mark Jansen <mark.jansen(a)reactos.org>
Reviewed-by: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
Reviewed-by: Giannis Adamopoulos <gadamopoulos(a)reactos.org>
Reviewed-by: Stanislav Motylkov <x86corez(a)gmail.com>
---
dll/win32/shell32/CDefView.cpp | 146 ++++++++++++++++++++++++----
dll/win32/shell32/folders/CDrivesFolder.cpp | 11 ---
dll/win32/shell32/wine/pidl.c | 11 +++
dll/win32/shell32/wine/pidl.h | 1 +
4 files changed, 139 insertions(+), 30 deletions(-)
diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp
index 8ee02097f55..67889f4aedc 100644
--- a/dll/win32/shell32/CDefView.cpp
+++ b/dll/win32/shell32/CDefView.cpp
@@ -2,6 +2,7 @@
* ShellView
*
* Copyright 1998,1999 <juergen.schmied(a)debitel.net>
+ * Copyright 2022 Russell Johnson <russell.johnson(a)superdark.net>
*
* This is the view visualizing the data provided by the shellfolder.
* No direct access to data from pidls should be done from here.
@@ -117,11 +118,14 @@ class CDefView :
CComPtr<IContextMenu> m_pCM;
BOOL m_isEditing;
+ BOOL m_isParentFolderSpecial;
CLSID m_Category;
BOOL m_Destroyed;
SFVM_CUSTOMVIEWINFO_DATA m_viewinfo_data;
+ HICON m_hMyComputerIcon;
+
private:
HRESULT _MergeToolbar();
BOOL _Sort();
@@ -129,6 +133,8 @@ class CDefView :
HRESULT _GetSnapToGrid();
void _MoveSelectionOnAutoArrange(POINT pt);
INT _FindInsertableIndexFromPoint(POINT pt);
+ void _HandleStatusBarResize(int width);
+ void _ForceStatusBarResize();
public:
CDefView();
@@ -393,6 +399,7 @@ CDefView::CDefView() :
m_iDragOverItem(0),
m_cScrollDelay(0),
m_isEditing(FALSE),
+ m_isParentFolderSpecial(FALSE),
m_Destroyed(FALSE)
{
ZeroMemory(&m_FolderSettings, sizeof(m_FolderSettings));
@@ -402,6 +409,8 @@ CDefView::CDefView() :
m_viewinfo_data.clrText = GetSysColor(COLOR_WINDOWTEXT);
m_viewinfo_data.clrTextBack = GetSysColor(COLOR_WINDOW);
m_viewinfo_data.hbmBack = NULL;
+
+ m_hMyComputerIcon = LoadIconW(shell32_hInstance,
MAKEINTRESOURCEW(IDI_SHELL_COMPUTER_DESKTOP));
}
CDefView::~CDefView()
@@ -505,21 +514,74 @@ void CDefView::CheckToolbar()
void CDefView::UpdateStatusbar()
{
WCHAR szFormat[MAX_PATH] = {0};
- WCHAR szObjects[MAX_PATH] = {0};
+ WCHAR szPartText[MAX_PATH] = {0};
UINT cSelectedItems;
cSelectedItems = m_ListView.GetSelectedCount();
if (cSelectedItems)
{
LoadStringW(shell32_hInstance, IDS_OBJECTS_SELECTED, szFormat,
_countof(szFormat));
- StringCchPrintfW(szObjects, MAX_PATH, szFormat, cSelectedItems);
+ StringCchPrintfW(szPartText, _countof(szPartText), szFormat, cSelectedItems);
}
else
{
LoadStringW(shell32_hInstance, IDS_OBJECTS, szFormat, _countof(szFormat));
- StringCchPrintfW(szObjects, MAX_PATH, szFormat, m_ListView.GetItemCount());
+ StringCchPrintfW(szPartText, _countof(szPartText), szFormat,
m_ListView.GetItemCount());
+ }
+
+ LRESULT lResult;
+ 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)
+ {
+ DWORD uTotalFileSize = 0;
+ WORD uFileFlags = LVNI_ALL;
+ LPARAM pIcon = NULL;
+ INT nItem = -1;
+ bool bIsOnlyFoldersSelected = true;
+
+ /* If we have something selected then only count selected file sizes. */
+ if (cSelectedItems)
+ {
+ uFileFlags = LVNI_SELECTED;
+ }
+
+ while ((nItem = m_ListView.GetNextItem(nItem, uFileFlags)) >= 0)
+ {
+ PCUITEMID_CHILD pidl = _PidlByItem(nItem);
+
+ uTotalFileSize += _ILGetFileSize(pidl, NULL, 0);
+
+ if (!_ILIsFolder(pidl))
+ {
+ bIsOnlyFoldersSelected = false;
+ }
+ }
+
+ /* 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 folder 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);
}
- m_pShellBrowser->SetStatusTextSB(szObjects);
}
/**********************************************************
@@ -1196,6 +1258,21 @@ 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 = _ILIsDesktop(m_pidlParent) || _ILIsNetHood(m_pidlParent)
+ || _ILIsControlPanel(ILFindLastID(m_pidlParent));
+
+ /* Only force StatusBar part refresh if the state
+ * changed from the previous folder. */
+ if (bPreviousParentSpecial != m_isParentFolderSpecial)
+ {
+ /* This handles changing StatusBar parts. */
+ _ForceStatusBarResize();
+ }
+
UpdateStatusbar();
return S_OK;
@@ -1645,6 +1722,9 @@ LRESULT CDefView::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL &bHandled
_DoFolderViewCB(SFVM_SIZE, 0, 0);
+ _HandleStatusBarResize(wWidth);
+ UpdateStatusbar();
+
return 0;
}
@@ -2432,10 +2512,6 @@ HRESULT WINAPI CDefView::EnableModeless(BOOL fEnable)
HRESULT WINAPI CDefView::UIActivate(UINT uState)
{
- // CHAR szName[MAX_PATH];
- LRESULT lResult;
- int nPartArray[1] = { -1};
-
TRACE("(%p)->(state=%x) stub\n", this, uState);
/* don't do anything if the state isn't really changing */
@@ -2450,18 +2526,10 @@ HRESULT WINAPI CDefView::UIActivate(UINT uState)
/* only do This if we are active */
if (uState != SVUIA_DEACTIVATE)
{
+ _ForceStatusBarResize();
- /*
- GetFolderPath is not a method of IShellFolder
- IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
- */
- /* set the number of parts */
- m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, 1,
(LPARAM)nPartArray, &lResult);
-
- /* set the text for the parts */
- /*
- m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0,
(LPARAM)szName, &lResult);
- */
+ /* Set the text for the status bar */
+ UpdateStatusbar();
}
return S_OK;
@@ -3503,6 +3571,46 @@ INT CDefView::_FindInsertableIndexFromPoint(POINT pt)
return nCount;
}
+void CDefView::_HandleStatusBarResize(int nWidth)
+{
+ LRESULT lResult;
+
+ if (m_isParentFolderSpecial)
+ {
+ int nPartArray[] = {-1};
+ m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray),
(LPARAM)nPartArray, &lResult);
+ return;
+ }
+
+ int nFileSizePartLength = 125;
+ const int nLocationPartLength = 150;
+ const int nRightPartsLength = nFileSizePartLength + nLocationPartLength;
+ int nObjectsPartLength = nWidth - nRightPartsLength;
+
+ /* If the window is small enough just divide each part into thirds
+ * This is the behavior of Windows Server 2003. */
+ if (nObjectsPartLength <= nLocationPartLength)
+ nObjectsPartLength = nFileSizePartLength = nWidth / 3;
+
+ int nPartArray[] = {nObjectsPartLength, nObjectsPartLength + nFileSizePartLength,
-1};
+
+ m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray),
(LPARAM)nPartArray, &lResult);
+}
+
+void CDefView::_ForceStatusBarResize()
+{
+ /* Get the handle for the status bar */
+ HWND fStatusBar;
+ m_pShellBrowser->GetControlWindow(FCW_STATUS, &fStatusBar);
+
+ /* Get the size of our status bar */
+ RECT statusBarSize;
+ ::GetWindowRect(fStatusBar, &statusBarSize);
+
+ /* Resize the status bar */
+ _HandleStatusBarResize(statusBarSize.right - statusBarSize.left);
+}
+
typedef CSimpleMap<LPARAM, INT> CLParamIndexMap;
static INT CALLBACK
diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp
b/dll/win32/shell32/folders/CDrivesFolder.cpp
index a64182e1dc9..fe5e8f5bb38 100644
--- a/dll/win32/shell32/folders/CDrivesFolder.cpp
+++ b/dll/win32/shell32/folders/CDrivesFolder.cpp
@@ -819,17 +819,6 @@ HRESULT WINAPI CDrivesFolder::CreateViewObject(HWND hwndOwner, REFIID
riid, LPVO
return hr;
}
-static BOOL _ILIsControlPanel(LPCITEMIDLIST pidl)
-{
- GUID *guid = _ILGetGUIDPointer(pidl);
-
- TRACE("(%p)\n", pidl);
-
- if (guid)
- return IsEqualIID(*guid, CLSID_ControlPanel);
- return FALSE;
-}
-
/**************************************************************************
* CDrivesFolder::GetAttributesOf
*/
diff --git a/dll/win32/shell32/wine/pidl.c b/dll/win32/shell32/wine/pidl.c
index 1f27557db9b..2ee8c4650fc 100644
--- a/dll/win32/shell32/wine/pidl.c
+++ b/dll/win32/shell32/wine/pidl.c
@@ -1917,6 +1917,17 @@ BOOL _ILIsNetHood(LPCITEMIDLIST pidl)
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 7e8c5200df9..e6e0bd6425e 100644
--- a/dll/win32/shell32/wine/pidl.h
+++ b/dll/win32/shell32/wine/pidl.h
@@ -239,6 +239,7 @@ BOOL _ILIsMyComputer (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;
BOOL _ILIsMyDocuments (LPCITEMIDLIST pidl);
BOOL _ILIsBitBucket (LPCITEMIDLIST pidl);
BOOL _ILIsNetHood (LPCITEMIDLIST pidl);
+BOOL _ILIsControlPanel (LPCITEMIDLIST pidl);
#endif
BOOL _ILIsDrive (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;
BOOL _ILIsFolder (LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;