diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp index 50af36089db..2d04d035073 100644 --- a/dll/win32/shell32/CDefView.cpp +++ b/dll/win32/shell32/CDefView.cpp @@ -199,7 +199,7 @@ public: int LV_AddItem(PCUITEMID_CHILD pidl); BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl); 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); HRESULT FillList(); HRESULT FillFileMenu(); @@ -214,6 +214,7 @@ public: HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); HRESULT InvokeContextMenuCommand(CComPtr& pCM, LPCSTR lpVerb, POINT* pt = NULL); LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection); + void RefreshIcons(); // *** IOleWindow methods *** STDMETHOD(GetWindow)(HWND *lphwnd) override; @@ -973,6 +974,8 @@ BOOLEAN CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl) if (nIndex < 0) return FALSE; + _DoFolderViewCB(SFVM_REMOVINGOBJECT, 0, (LPARAM)pidl); + return m_ListView.DeleteItem(nIndex); } @@ -1015,7 +1018,7 @@ BOOLEAN CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew return FALSE; } -BOOLEAN CDefView::LV_ProdItem(PCUITEMID_CHILD pidl) +BOOLEAN CDefView::LV_UpdateItem(PCUITEMID_CHILD pidl) { int nItem; LVITEMW lvItem; @@ -1028,6 +1031,8 @@ BOOLEAN CDefView::LV_ProdItem(PCUITEMID_CHILD pidl) if (-1 != nItem) { + _DoFolderViewCB(SFVM_UPDATINGOBJECT, 0, (LPARAM)pidl); + lvItem.mask = LVIF_IMAGE; lvItem.iItem = nItem; lvItem.iSubItem = 0; @@ -2294,6 +2299,24 @@ static BOOL ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE 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) { // The change notify can come before WM_CREATE @@ -2311,49 +2334,81 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & 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); + // Translate PIDLs. + // SHSimpleIDListFromPathW creates fake PIDLs (lacking some attributes) + CComHeapPtr 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; switch (lEvent) { case SHCNE_MKDIR: case SHCNE_CREATE: case SHCNE_DRIVEADD: - if (bParent0) - { - if (LV_FindItemByPidl(ILFindLastID(Pidls[0])) == -1) - LV_AddItem(ILFindLastID(Pidls[0])); - else - LV_ProdItem(ILFindLastID(Pidls[0])); - } + if (!child0) + break; + if (LV_FindItemByPidl(child0) < 0) + LV_AddItem(child0); + else + LV_UpdateItem(child0); break; case SHCNE_RMDIR: case SHCNE_DELETE: case SHCNE_DRIVEREMOVED: - if (bParent0) - LV_DeleteItem(ILFindLastID(Pidls[0])); + if (child0) + LV_DeleteItem(child0); break; case SHCNE_RENAMEFOLDER: case SHCNE_RENAMEITEM: - if (bParent0 && bParent1) - LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[1])); - else if (bParent0) - LV_DeleteItem(ILFindLastID(Pidls[0])); - else if (bParent1) - LV_AddItem(ILFindLastID(Pidls[1])); + if (child0 && child1) + LV_RenameItem(child0, child1); + else if (child0) + LV_DeleteItem(child0); + else if (child1) + LV_AddItem(child1); break; case SHCNE_UPDATEITEM: - if (bParent0) - LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0])); + if (child0) + LV_UpdateItem(child0); + break; + case SHCNE_UPDATEIMAGE: + RefreshIcons(); break; case SHCNE_UPDATEDIR: + case SHCNE_ASSOCCHANGED: + case SHCNE_MEDIAINSERTED: + case SHCNE_MEDIAREMOVED: Refresh(); break; + case SHCNE_FREESPACE: + UpdateStatusbar(); + break; } + ILFree(Pidls[0]); + ILFree(Pidls[1]); SHChangeNotification_Unlock(hLock); return TRUE; } diff --git a/dll/win32/shell32/folders/CFSFolder.cpp b/dll/win32/shell32/folders/CFSFolder.cpp index b89ecc45579..95a5030a2d3 100644 --- a/dll/win32/shell32/folders/CFSFolder.cpp +++ b/dll/win32/shell32/folders/CFSFolder.cpp @@ -683,6 +683,7 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDW return S_OK; } +// This method is typically invoked from SHSimpleIDListFromPathA/W. HRESULT CFSFolder::_ParseSimple( _In_ LPOLESTR lpszDisplayName, _Inout_ WIN32_FIND_DATAW *pFind, diff --git a/dll/win32/shell32/folders/CRecycleBin.cpp b/dll/win32/shell32/folders/CRecycleBin.cpp index c8bceb589f4..f67b3eca791 100644 --- a/dll/win32/shell32/folders/CRecycleBin.cpp +++ b/dll/win32/shell32/folders/CRecycleBin.cpp @@ -1078,6 +1078,10 @@ EXTERN_C HRESULT WINAPI SHUpdateRecycleBinIcon(void) { FIXME("stub\n"); + /* HACK! */ + LPITEMIDLIST pidl = _ILCreateBitBucket(); + SHChangeNotify(SHCNE_UPDATEIMAGE, SHCNF_IDLIST, pidl, NULL); + ILFree(pidl); return S_OK; } diff --git a/dll/win32/shell32/shlfileop.cpp b/dll/win32/shell32/shlfileop.cpp index f1ecc455428..5e1309aabdf 100644 --- a/dll/win32/shell32/shlfileop.cpp +++ b/dll/win32/shell32/shlfileop.cpp @@ -2061,6 +2061,8 @@ cleanup: if (lpFileOp->wFunc != FO_DELETE) destroy_file_list(&flTo); + else if (lpFileOp->fFlags & FOF_ALLOWUNDO) + SHUpdateRecycleBinIcon(); if (ret == ERROR_CANCELLED) lpFileOp->fAnyOperationsAborted = TRUE; diff --git a/dll/win32/shell32/wine/pidl.c b/dll/win32/shell32/wine/pidl.c index 824af18984a..33495aead3a 100644 --- a/dll/win32/shell32/wine/pidl.c +++ b/dll/win32/shell32/wine/pidl.c @@ -1113,15 +1113,6 @@ LPITEMIDLIST WINAPI SHSimpleIDListFromPathA(LPCSTR lpszPath) wPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 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); @@ -1135,13 +1126,9 @@ LPITEMIDLIST WINAPI SHSimpleIDListFromPathW(LPCWSTR lpszPath) LPITEMIDLIST pidl = NULL; 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); + TRACE("%s %p\n", debugstr_w(lpszPath), pidl); return pidl; } diff --git a/sdk/include/psdk/shlobj.h b/sdk/include/psdk/shlobj.h index 3d27f328631..bd60c13064c 100644 --- a/sdk/include/psdk/shlobj.h +++ b/sdk/include/psdk/shlobj.h @@ -1323,6 +1323,7 @@ SHCreateShellFolderViewEx( #define SFVM_SETISFV 39 #define SFVM_GETEXTVIEWS 40 /* undocumented */ #define SFVM_THISIDLIST 41 +#define SFVM_UPDATINGOBJECT 43 /* undocumented */ #define SFVM_ADDPROPERTYPAGES 47 #define SFVM_BACKGROUNDENUMDONE 48 #define SFVM_GETNOTIFY 49 diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h index 0460a261cb7..94f6bf71702 100644 --- a/sdk/include/reactos/undocshell.h +++ b/sdk/include/reactos/undocshell.h @@ -122,6 +122,7 @@ typedef struct _SHCNF_PRINTJOB_INFO #define SHCNF_PRINTJOBA 0x0004 #define SHCNF_PRINTJOBW 0x0007 +HRESULT WINAPI SHUpdateRecycleBinIcon(void); /**************************************************************************** * Shell Common Dialogs