[BROWSEUI] CExplorerBand: Use SHCNRF_NewDelivery method (#7133)

Refactoring. Optimize for speed.
JIRA issue: CORE-12619
- Update file headers.
- Make some parameter type LPITEMIDLIST
  LPCITEMIDLIST (Add const).
- Add OnChangeNotify method.
- Use SHCNRF_NewDelivery method for speed.
- Add some SAL annotations.
This commit is contained in:
Katayama Hirofumi MZ 2024-07-14 10:50:18 +09:00 committed by GitHub
parent 4093d0e164
commit 7bec458077
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 85 additions and 64 deletions

View file

@ -1,22 +1,9 @@
/*
* ReactOS Explorer
*
* Copyright 2016 Sylvain Deverre <deverre dot sylv at gmail dot com>
* Copyright 2020 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* PROJECT: ReactOS Explorer
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
* PURPOSE: Explorer bar
* COPYRIGHT: Copyright 2016 Sylvain Deverre <deverre.sylv@gmail.com>
* Copyright 2020-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
#include "precomp.h"
@ -87,7 +74,9 @@ HRESULT GetDisplayName(LPCITEMIDLIST pidlDirectory,TCHAR *szDisplayName,UINT cch
ill-formed PIDL stripped from useful data that parses incorrectly with SHGetFileInfo.
So we need to re-enumerate subfolders until we find one with the same name.
*/
HRESULT _ReparsePIDL(LPITEMIDLIST buggyPidl, LPITEMIDLIST *cleanPidl)
HRESULT _ReparsePIDL(
_In_ LPCITEMIDLIST buggyPidl,
_Out_ LPITEMIDLIST *cleanPidl)
{
HRESULT hr;
CComPtr<IShellFolder> folder;
@ -187,7 +176,7 @@ void CExplorerBand::InitializeExplorerBand()
TreeView_SetImageList(m_hWnd, (HIMAGELIST)piml, TVSIL_NORMAL);
// Insert the root node
m_hRoot = InsertItem(0, m_pDesktop, pidl, pidl, FALSE);
m_hRoot = InsertItem(NULL, m_pDesktop, pidl, pidl, FALSE);
if (!m_hRoot)
{
ERR("Failed to create root item\n");
@ -208,7 +197,7 @@ void CExplorerBand::InitializeExplorerBand()
shcne.fRecursive = TRUE;
m_shellRegID = SHChangeNotifyRegister(
m_hWnd,
SHCNRF_ShellLevel | SHCNRF_InterruptLevel | SHCNRF_RecursiveInterrupt,
SHCNRF_NewDelivery | SHCNRF_ShellLevel | SHCNRF_InterruptLevel | SHCNRF_RecursiveInterrupt,
SHCNE_DISKEVENTS | SHCNE_RENAMEFOLDER | SHCNE_RMDIR | SHCNE_MKDIR,
WM_USER_SHELLEVENT,
1,
@ -580,35 +569,59 @@ LRESULT CExplorerBand::ContextMenuHack(UINT uMsg, WPARAM wParam, LPARAM lParam,
return FALSE; /* let the wndproc process the message */
}
// WM_USER_SHELLEVENT
LRESULT CExplorerBand::OnShellEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
LPITEMIDLIST *dest;
// We use SHCNRF_NewDelivery method
HANDLE hChange = (HANDLE)wParam;
DWORD dwProcID = (DWORD)lParam;
PIDLIST_ABSOLUTE *ppidl = NULL;
LONG lEvent;
HANDLE hLock = SHChangeNotification_Lock(hChange, dwProcID, &ppidl, &lEvent);
if (hLock == NULL)
{
ERR("hLock == NULL\n");
return 0;
}
OnChangeNotify(ppidl[0], ppidl[1], (lEvent & ~SHCNE_INTERRUPT));
SHChangeNotification_Unlock(hLock);
return 0;
}
void
CExplorerBand::OnChangeNotify(
_In_opt_ LPCITEMIDLIST pidl0,
_In_opt_ LPCITEMIDLIST pidl1,
_In_ LONG lEvent)
{
LPITEMIDLIST clean;
HTREEITEM pItem;
dest = (LPITEMIDLIST*)wParam;
/* TODO: handle shell notifications */
switch(lParam & ~SHCNE_INTERRUPT)
switch (lEvent)
{
case SHCNE_MKDIR:
if (!SUCCEEDED(_ReparsePIDL(dest[0], &clean)))
if (!SUCCEEDED(_ReparsePIDL(pidl0, &clean)))
{
ERR("Can't reparse PIDL to a valid one\n");
return FALSE;
break;
}
NavigateToPIDL(clean, &pItem, FALSE, TRUE, FALSE);
ILFree(clean);
break;
case SHCNE_RMDIR:
DeleteItem(dest[0]);
DeleteItem(pidl0);
break;
case SHCNE_RENAMEFOLDER:
if (!SUCCEEDED(_ReparsePIDL(dest[1], &clean)))
if (!SUCCEEDED(_ReparsePIDL(pidl1, &clean)))
{
ERR("Can't reparse PIDL to a valid one\n");
return FALSE;
break;
}
if (NavigateToPIDL(dest[0], &pItem, FALSE, FALSE, FALSE))
if (NavigateToPIDL(pidl0, &pItem, FALSE, FALSE, FALSE))
RenameItem(pItem, clean);
ILFree(clean);
break;
@ -619,7 +632,6 @@ LRESULT CExplorerBand::OnShellEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOO
default:
TRACE("Unhandled message\n");
}
return TRUE;
}
LRESULT CExplorerBand::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
@ -638,7 +650,13 @@ LRESULT CExplorerBand::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
}
// *** Helper functions ***
HTREEITEM CExplorerBand::InsertItem(HTREEITEM hParent, IShellFolder *psfParent, LPITEMIDLIST pElt, LPITEMIDLIST pEltRelative, BOOL bSort)
HTREEITEM
CExplorerBand::InsertItem(
_In_opt_ HTREEITEM hParent,
_Inout_ IShellFolder *psfParent,
_In_ LPCITEMIDLIST pElt,
_In_ LPCITEMIDLIST pEltRelative,
_In_ BOOL bSort)
{
TV_INSERTSTRUCT tvInsert;
HTREEITEM htiCreated;
@ -707,7 +725,12 @@ HTREEITEM CExplorerBand::InsertItem(HTREEITEM hParent, IShellFolder *psfParent,
}
/* This is the slow version of the above method */
HTREEITEM CExplorerBand::InsertItem(HTREEITEM hParent, LPITEMIDLIST pElt, LPITEMIDLIST pEltRelative, BOOL bSort)
HTREEITEM
CExplorerBand::InsertItem(
_In_opt_ HTREEITEM hParent,
_In_ LPCITEMIDLIST pElt,
_In_ LPCITEMIDLIST pEltRelative,
_In_ BOOL bSort)
{
CComPtr<IShellFolder> psfFolder;
HRESULT hr = SHBindToParent(pElt, IID_PPV_ARG(IShellFolder, &psfFolder), NULL);
@ -805,7 +828,7 @@ BOOL CExplorerBand::InsertSubitems(HTREEITEM hItem, NodeInfo *pNodeInfo)
* - bInsert: insert the element at the right place if we don't find it
* - bSelect: select the item after we found it
*/
BOOL CExplorerBand::NavigateToPIDL(LPITEMIDLIST dest, HTREEITEM *item, BOOL bExpand, BOOL bInsert,
BOOL CExplorerBand::NavigateToPIDL(LPCITEMIDLIST dest, HTREEITEM *item, BOOL bExpand, BOOL bInsert,
BOOL bSelect)
{
HTREEITEM current;
@ -917,7 +940,7 @@ BOOL CExplorerBand::NavigateToCurrentFolder()
return result;
}
BOOL CExplorerBand::DeleteItem(LPITEMIDLIST idl)
BOOL CExplorerBand::DeleteItem(LPCITEMIDLIST idl)
{
HTREEITEM toDelete;
TVITEM tvItem;
@ -950,7 +973,7 @@ BOOL CExplorerBand::DeleteItem(LPITEMIDLIST idl)
return TRUE;
}
BOOL CExplorerBand::RenameItem(HTREEITEM toRename, LPITEMIDLIST newPidl)
BOOL CExplorerBand::RenameItem(HTREEITEM toRename, LPCITEMIDLIST newPidl)
{
WCHAR wszDisplayName[MAX_PATH];
TVITEM itemInfo;
@ -1000,7 +1023,7 @@ BOOL CExplorerBand::RenameItem(HTREEITEM toRename, LPITEMIDLIST newPidl)
return TRUE;
}
BOOL CExplorerBand::RefreshTreePidl(HTREEITEM tree, LPITEMIDLIST pidlParent)
BOOL CExplorerBand::RefreshTreePidl(HTREEITEM tree, LPCITEMIDLIST pidlParent)
{
HTREEITEM tmp;
NodeInfo *pInfo;
@ -1340,7 +1363,6 @@ HRESULT STDMETHODCALLTYPE CExplorerBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
return E_NOTIMPL;
}
// *** IWinEventHandler methods ***
HRESULT STDMETHODCALLTYPE CExplorerBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
{

View file

@ -1,28 +1,14 @@
/*
* ReactOS Explorer
*
* Copyright 2016 Sylvain Deverre <deverre dot sylv at gmail dot com>
* Copyright 2020 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* PROJECT: ReactOS Explorer
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
* PURPOSE: Explorer bar
* COPYRIGHT: Copyright 2016 Sylvain Deverre <deverre dot sylv at gmail dot com>
* Copyright 2020-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
#pragma once
#define WM_USER_SHELLEVENT WM_USER+88
#define WM_USER_FOLDEREVENT WM_USER+88
#define WM_USER_SHELLEVENT (WM_USER + 88)
class CExplorerBand :
public CComCoClass<CExplorerBand, &CLSID_ExplorerBand>,
@ -95,16 +81,29 @@ private:
// *** Helper functions ***
NodeInfo* GetNodeInfo(HTREEITEM hItem);
HRESULT UpdateBrowser(LPITEMIDLIST pidlGoto);
HTREEITEM InsertItem(HTREEITEM hParent, IShellFolder *psfParent, LPITEMIDLIST pElt, LPITEMIDLIST pEltRelative, BOOL bSort);
HTREEITEM InsertItem(HTREEITEM hParent, LPITEMIDLIST pElt, LPITEMIDLIST pEltRelative, BOOL bSort);
HTREEITEM InsertItem(
_In_opt_ HTREEITEM hParent,
_Inout_ IShellFolder *psfParent,
_In_ LPCITEMIDLIST pElt,
_In_ LPCITEMIDLIST pEltRelative,
_In_ BOOL bSort);
HTREEITEM InsertItem(
_In_opt_ HTREEITEM hParent,
_In_ LPCITEMIDLIST pElt,
_In_ LPCITEMIDLIST pEltRelative,
_In_ BOOL bSort);
BOOL InsertSubitems(HTREEITEM hItem, NodeInfo *pNodeInfo);
BOOL NavigateToPIDL(LPITEMIDLIST dest, HTREEITEM *item, BOOL bExpand, BOOL bInsert, BOOL bSelect);
BOOL DeleteItem(LPITEMIDLIST toDelete);
BOOL RenameItem(HTREEITEM toRename, LPITEMIDLIST newPidl);
BOOL RefreshTreePidl(HTREEITEM tree, LPITEMIDLIST pidlParent);
BOOL NavigateToPIDL(LPCITEMIDLIST dest, HTREEITEM *item, BOOL bExpand, BOOL bInsert, BOOL bSelect);
BOOL DeleteItem(LPCITEMIDLIST toDelete);
BOOL RenameItem(HTREEITEM toRename, LPCITEMIDLIST newPidl);
BOOL RefreshTreePidl(HTREEITEM tree, LPCITEMIDLIST pidlParent);
BOOL NavigateToCurrentFolder();
HRESULT GetCurrentLocation(PIDLIST_ABSOLUTE &pidl);
HRESULT IsCurrentLocation(PCIDLIST_ABSOLUTE pidl);
void OnChangeNotify(
_In_opt_ LPCITEMIDLIST pidl0,
_In_opt_ LPCITEMIDLIST pidl1,
_In_ LONG lEvent);
// *** Tree item sorting callback ***
static int CALLBACK CompareTreeItems(LPARAM p1, LPARAM p2, LPARAM p3);