[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@superdark.net>
Reviewed-by: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Reviewed-by: Mark Jansen <mark.jansen@reactos.org>
Reviewed-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>	
Reviewed-by: Giannis Adamopoulos <gadamopoulos@reactos.org>	
Reviewed-by: Stanislav Motylkov <x86corez@gmail.com>
This commit is contained in:
Russell Johnson 2022-05-03 06:52:23 -07:00 committed by GitHub
parent 2ef605d428
commit 3e2df36561
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 139 additions and 30 deletions

View file

@ -2,6 +2,7 @@
* ShellView
*
* Copyright 1998,1999 <juergen.schmied@debitel.net>
* Copyright 2022 Russell Johnson <russell.johnson@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

View file

@ -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
*/

View file

@ -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);

View file

@ -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;