[SHELL32][SDK] SHChangeNotify: Re-work Part 1

This commit is contained in:
Katayama Hirofumi MZ 2024-05-16 09:35:05 +09:00
parent 48a0d8e012
commit d5931313bc
7 changed files with 87 additions and 36 deletions

View file

@ -199,7 +199,7 @@ public:
int LV_AddItem(PCUITEMID_CHILD pidl); int LV_AddItem(PCUITEMID_CHILD pidl);
BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl); BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl);
BOOLEAN LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew); BOOLEAN LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew);
BOOLEAN LV_ProdItem(PCUITEMID_CHILD pidl); BOOLEAN LV_UpdateItem(PCUITEMID_CHILD pidl);
static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg); static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg);
HRESULT FillList(); HRESULT FillList();
HRESULT FillFileMenu(); HRESULT FillFileMenu();
@ -214,6 +214,7 @@ public:
HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
HRESULT InvokeContextMenuCommand(CComPtr<IContextMenu>& pCM, LPCSTR lpVerb, POINT* pt = NULL); HRESULT InvokeContextMenuCommand(CComPtr<IContextMenu>& pCM, LPCSTR lpVerb, POINT* pt = NULL);
LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection); LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection);
void RefreshIcons();
// *** IOleWindow methods *** // *** IOleWindow methods ***
STDMETHOD(GetWindow)(HWND *lphwnd) override; STDMETHOD(GetWindow)(HWND *lphwnd) override;
@ -973,6 +974,8 @@ BOOLEAN CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl)
if (nIndex < 0) if (nIndex < 0)
return FALSE; return FALSE;
_DoFolderViewCB(SFVM_REMOVINGOBJECT, 0, (LPARAM)pidl);
return m_ListView.DeleteItem(nIndex); return m_ListView.DeleteItem(nIndex);
} }
@ -1015,7 +1018,7 @@ BOOLEAN CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew
return FALSE; return FALSE;
} }
BOOLEAN CDefView::LV_ProdItem(PCUITEMID_CHILD pidl) BOOLEAN CDefView::LV_UpdateItem(PCUITEMID_CHILD pidl)
{ {
int nItem; int nItem;
LVITEMW lvItem; LVITEMW lvItem;
@ -1028,6 +1031,8 @@ BOOLEAN CDefView::LV_ProdItem(PCUITEMID_CHILD pidl)
if (-1 != nItem) if (-1 != nItem)
{ {
_DoFolderViewCB(SFVM_UPDATINGOBJECT, 0, (LPARAM)pidl);
lvItem.mask = LVIF_IMAGE; lvItem.mask = LVIF_IMAGE;
lvItem.iItem = nItem; lvItem.iItem = nItem;
lvItem.iSubItem = 0; lvItem.iSubItem = 0;
@ -2294,6 +2299,24 @@ static BOOL ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE
return FALSE; return FALSE;
} }
void CDefView::RefreshIcons()
{
ASSERT(m_ListView);
LVITEMW lvItem = { LVIF_IMAGE };
for (INT iItem = -1;;)
{
iItem = ListView_GetNextItem(m_ListView, iItem, LVNI_ALL);
if (iItem == -1)
break;
lvItem.iItem = iItem;
lvItem.iImage = I_IMAGECALLBACK;
m_ListView.SetItem(&lvItem);
m_ListView.Update(iItem);
}
}
LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{ {
// The change notify can come before WM_CREATE // The change notify can come before WM_CREATE
@ -2311,49 +2334,81 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
return FALSE; return FALSE;
} }
BOOL bParent0 = ILIsParentOrSpecialParent(m_pidlParent, Pidls[0]);
BOOL bParent1 = ILIsParentOrSpecialParent(m_pidlParent, Pidls[1]);
TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls[0], Pidls[1], lParam); TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls[0], Pidls[1], lParam);
// Translate PIDLs.
// SHSimpleIDListFromPathW creates fake PIDLs (lacking some attributes)
CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidl0, pidl1;
WCHAR path0[MAX_PATH], path1[MAX_PATH];
if (Pidls[0])
{
if (SHGetPathFromIDListW(Pidls[0], path0) && PathFileExistsW(path0))
pidl0.Attach(ILCreateFromPathW(path0));
else
pidl0.Attach(ILClone(Pidls[0]));
}
if (Pidls[1])
{
if (SHGetPathFromIDListW(Pidls[1], path1) && PathFileExistsW(path1))
pidl1.Attach(ILCreateFromPathW(path1));
else
pidl1.Attach(ILClone(Pidls[1]));
}
PITEMID_CHILD child0 = NULL, child1 = NULL;
if (ILIsParentOrSpecialParent(m_pidlParent, pidl0))
child0 = ILFindLastID(pidl0);
if (ILIsParentOrSpecialParent(m_pidlParent, pidl1))
child1 = ILFindLastID(pidl1);
lEvent &= ~SHCNE_INTERRUPT; lEvent &= ~SHCNE_INTERRUPT;
switch (lEvent) switch (lEvent)
{ {
case SHCNE_MKDIR: case SHCNE_MKDIR:
case SHCNE_CREATE: case SHCNE_CREATE:
case SHCNE_DRIVEADD: case SHCNE_DRIVEADD:
if (bParent0) if (!child0)
{ break;
if (LV_FindItemByPidl(ILFindLastID(Pidls[0])) == -1) if (LV_FindItemByPidl(child0) < 0)
LV_AddItem(ILFindLastID(Pidls[0])); LV_AddItem(child0);
else else
LV_ProdItem(ILFindLastID(Pidls[0])); LV_UpdateItem(child0);
}
break; break;
case SHCNE_RMDIR: case SHCNE_RMDIR:
case SHCNE_DELETE: case SHCNE_DELETE:
case SHCNE_DRIVEREMOVED: case SHCNE_DRIVEREMOVED:
if (bParent0) if (child0)
LV_DeleteItem(ILFindLastID(Pidls[0])); LV_DeleteItem(child0);
break; break;
case SHCNE_RENAMEFOLDER: case SHCNE_RENAMEFOLDER:
case SHCNE_RENAMEITEM: case SHCNE_RENAMEITEM:
if (bParent0 && bParent1) if (child0 && child1)
LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[1])); LV_RenameItem(child0, child1);
else if (bParent0) else if (child0)
LV_DeleteItem(ILFindLastID(Pidls[0])); LV_DeleteItem(child0);
else if (bParent1) else if (child1)
LV_AddItem(ILFindLastID(Pidls[1])); LV_AddItem(child1);
break; break;
case SHCNE_UPDATEITEM: case SHCNE_UPDATEITEM:
if (bParent0) if (child0)
LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0])); LV_UpdateItem(child0);
break;
case SHCNE_UPDATEIMAGE:
RefreshIcons();
break; break;
case SHCNE_UPDATEDIR: case SHCNE_UPDATEDIR:
case SHCNE_ASSOCCHANGED:
case SHCNE_MEDIAINSERTED:
case SHCNE_MEDIAREMOVED:
Refresh(); Refresh();
break; break;
case SHCNE_FREESPACE:
UpdateStatusbar();
break;
} }
ILFree(Pidls[0]);
ILFree(Pidls[1]);
SHChangeNotification_Unlock(hLock); SHChangeNotification_Unlock(hLock);
return TRUE; return TRUE;
} }

View file

@ -683,6 +683,7 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDW
return S_OK; return S_OK;
} }
// This method is typically invoked from SHSimpleIDListFromPathA/W.
HRESULT CFSFolder::_ParseSimple( HRESULT CFSFolder::_ParseSimple(
_In_ LPOLESTR lpszDisplayName, _In_ LPOLESTR lpszDisplayName,
_Inout_ WIN32_FIND_DATAW *pFind, _Inout_ WIN32_FIND_DATAW *pFind,

View file

@ -1078,6 +1078,10 @@ EXTERN_C HRESULT WINAPI SHUpdateRecycleBinIcon(void)
{ {
FIXME("stub\n"); FIXME("stub\n");
/* HACK! */
LPITEMIDLIST pidl = _ILCreateBitBucket();
SHChangeNotify(SHCNE_UPDATEIMAGE, SHCNF_IDLIST, pidl, NULL);
ILFree(pidl);
return S_OK; return S_OK;
} }

View file

@ -2061,6 +2061,8 @@ cleanup:
if (lpFileOp->wFunc != FO_DELETE) if (lpFileOp->wFunc != FO_DELETE)
destroy_file_list(&flTo); destroy_file_list(&flTo);
else if (lpFileOp->fFlags & FOF_ALLOWUNDO)
SHUpdateRecycleBinIcon();
if (ret == ERROR_CANCELLED) if (ret == ERROR_CANCELLED)
lpFileOp->fAnyOperationsAborted = TRUE; lpFileOp->fAnyOperationsAborted = TRUE;

View file

@ -1113,15 +1113,6 @@ LPITEMIDLIST WINAPI SHSimpleIDListFromPathA(LPCSTR lpszPath)
wPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); wPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, lpszPath, -1, wPath, len); MultiByteToWideChar(CP_ACP, 0, lpszPath, -1, wPath, len);
} }
#ifdef __REACTOS__
// FIXME: Needs folder attribute
if (PathFileExistsW(wPath))
{
pidl = ILCreateFromPathW(wPath);
HeapFree(GetProcessHeap(), 0, wPath);
return pidl;
}
#endif
_ILParsePathW(wPath, NULL, TRUE, &pidl, NULL); _ILParsePathW(wPath, NULL, TRUE, &pidl, NULL);
@ -1135,13 +1126,9 @@ LPITEMIDLIST WINAPI SHSimpleIDListFromPathW(LPCWSTR lpszPath)
LPITEMIDLIST pidl = NULL; LPITEMIDLIST pidl = NULL;
TRACE("%s\n", debugstr_w(lpszPath)); TRACE("%s\n", debugstr_w(lpszPath));
#ifdef __REACTOS__
// FIXME: Needs folder attribute
if (PathFileExistsW(lpszPath))
return ILCreateFromPathW(lpszPath);
#endif
_ILParsePathW(lpszPath, NULL, TRUE, &pidl, NULL); _ILParsePathW(lpszPath, NULL, TRUE, &pidl, NULL);
TRACE("%s %p\n", debugstr_w(lpszPath), pidl); TRACE("%s %p\n", debugstr_w(lpszPath), pidl);
return pidl; return pidl;
} }

View file

@ -1323,6 +1323,7 @@ SHCreateShellFolderViewEx(
#define SFVM_SETISFV 39 #define SFVM_SETISFV 39
#define SFVM_GETEXTVIEWS 40 /* undocumented */ #define SFVM_GETEXTVIEWS 40 /* undocumented */
#define SFVM_THISIDLIST 41 #define SFVM_THISIDLIST 41
#define SFVM_UPDATINGOBJECT 43 /* undocumented */
#define SFVM_ADDPROPERTYPAGES 47 #define SFVM_ADDPROPERTYPAGES 47
#define SFVM_BACKGROUNDENUMDONE 48 #define SFVM_BACKGROUNDENUMDONE 48
#define SFVM_GETNOTIFY 49 #define SFVM_GETNOTIFY 49

View file

@ -122,6 +122,7 @@ typedef struct _SHCNF_PRINTJOB_INFO
#define SHCNF_PRINTJOBA 0x0004 #define SHCNF_PRINTJOBA 0x0004
#define SHCNF_PRINTJOBW 0x0007 #define SHCNF_PRINTJOBW 0x0007
HRESULT WINAPI SHUpdateRecycleBinIcon(void);
/**************************************************************************** /****************************************************************************
* Shell Common Dialogs * Shell Common Dialogs