Author: tfaber
Date: Thu Mar 26 12:05:54 2015
New Revision: 66901
URL:
http://svn.reactos.org/svn/reactos?rev=66901&view=rev
Log:
[SHELL32]
- Correctly handle recursive change notifications in CDefView
- Remove desktop folder hack from SHChangeNotify and move it to CDefView until we have
ITranslateShellChangeNotify
Fixes phantom files/folders on desktop. Based on a patch by Huw Campbell.
CORE-8844
Modified:
trunk/reactos/dll/win32/shell32/CDefView.cpp
trunk/reactos/dll/win32/shell32/wine/changenotify.c
Modified: trunk/reactos/dll/win32/shell32/CDefView.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CDefView…
==============================================================================
--- trunk/reactos/dll/win32/shell32/CDefView.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/CDefView.cpp [iso-8859-1] Thu Mar 26 12:05:54 2015
@@ -93,6 +93,7 @@
UINT m_uState;
UINT m_cidl;
PCUITEMID_CHILD_ARRAY m_apidl;
+ PIDLIST_ABSOLUTE m_pidlParent;
LISTVIEW_SORT_INFO m_sortInfo;
ULONG m_hNotify; /* change notification handle */
HACCEL m_hAccel;
@@ -354,6 +355,7 @@
m_uState(0),
m_cidl(0),
m_apidl(NULL),
+ m_pidlParent(NULL),
m_hNotify(0),
m_hAccel(NULL),
m_dwAspects(0),
@@ -943,6 +945,7 @@
DestroyMenu(m_hMenu);
RevokeDragDrop(m_hWnd);
SHChangeNotifyDeregister(m_hNotify);
+ SHFree(m_pidlParent);
bHandled = FALSE;
return 0;
}
@@ -1000,12 +1003,10 @@
m_pSFParent->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
if (ppf2)
{
- PIDLIST_ABSOLUTE pidlParent;
- ppf2->GetCurFolder(&pidlParent);
+ ppf2->GetCurFolder(&m_pidlParent);
ntreg.fRecursive = TRUE;
- ntreg.pidl = pidlParent;
- m_hNotify = SHChangeNotifyRegister(m_hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS,
SHV_CHANGE_NOTIFY, 1, &ntreg);
- SHFree(pidlParent);
+ ntreg.pidl = m_pidlParent;
+ m_hNotify = SHChangeNotifyRegister(m_hWnd, SHCNRF_InterruptLevel |
SHCNRF_ShellLevel, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
}
m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW));
@@ -1848,12 +1849,48 @@
return 0;
}
+/*
+ * This is just a quick hack to make the desktop work correctly.
+ * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way
that
+ * a folder should know if it should update upon a change notification.
+ * It is exported by merged folders at a minimum.
+ */
+static BOOL ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2)
+{
+ if (!pidl1 || !pidl2)
+ return FALSE;
+ if (ILIsParent(pidl1, pidl2, TRUE))
+ return TRUE;
+
+ if (_ILIsDesktop(pidl1))
+ {
+ PIDLIST_ABSOLUTE deskpidl;
+ SHGetFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, &deskpidl);
+ if (ILIsParent(deskpidl, pidl2, TRUE))
+ {
+ ILFree(deskpidl);
+ return TRUE;
+ }
+ ILFree(deskpidl);
+ SHGetFolderLocation(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL, 0,
&deskpidl);
+ if (ILIsParent(deskpidl, pidl2, TRUE))
+ {
+ ILFree(deskpidl);
+ return TRUE;
+ }
+ ILFree(deskpidl);
+ }
+ return FALSE;
+}
+
/**********************************************************
* ShellView_OnChange()
*/
LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
&bHandled)
{
PCIDLIST_ABSOLUTE *Pidls = reinterpret_cast<PCIDLIST_ABSOLUTE*>(wParam);
+ 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);
@@ -1861,21 +1898,29 @@
{
case SHCNE_MKDIR:
case SHCNE_CREATE:
- LV_AddItem(ILFindLastID(Pidls[0]));
+ if (bParent0)
+ LV_AddItem(ILFindLastID(Pidls[0]));
break;
case SHCNE_RMDIR:
case SHCNE_DELETE:
- LV_DeleteItem(ILFindLastID(Pidls[0]));
+ if (bParent0)
+ LV_DeleteItem(ILFindLastID(Pidls[0]));
break;
case SHCNE_RENAMEFOLDER:
case SHCNE_RENAMEITEM:
- LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[1]));
+ 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[0]));
break;
case SHCNE_UPDATEITEM:
- LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0]));
+ if (bParent0)
+ LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0]));
break;
case SHCNE_UPDATEDIR:
Modified: trunk/reactos/dll/win32/shell32/wine/changenotify.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/wine/cha…
==============================================================================
--- trunk/reactos/dll/win32/shell32/wine/changenotify.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/wine/changenotify.c [iso-8859-1] Thu Mar 26 12:05:54
2015
@@ -255,28 +255,6 @@
return TRUE;
if( sub && ILIsParent( watched, changed, FALSE ) )
return TRUE;
-#ifdef __REACTOS__
- if (sub && _ILIsDesktop(watched)) {
- LPITEMIDLIST deskpidl;
- WCHAR wszPath[MAX_PATH];
- SHGetSpecialFolderPathW(0, wszPath, CSIDL_DESKTOPDIRECTORY, FALSE);
- deskpidl = SHSimpleIDListFromPathW(wszPath);
- if (ILIsParent(deskpidl, changed, TRUE))
- {
- ILFree(deskpidl);
- return TRUE;
- }
- ILFree(deskpidl);
- SHGetSpecialFolderPathW(0, wszPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
- deskpidl = SHSimpleIDListFromPathW(wszPath);
- if (ILIsParent(deskpidl, changed, TRUE))
- {
- ILFree(deskpidl);
- return TRUE;
- }
- ILFree(deskpidl);
- }
-#endif
return FALSE;
}