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.cpp?rev=66901&r1=66900&r2=66901&view=diff
==============================================================================
--- 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/changenotify.c?rev=66901&r1=66900&r2=66901&view=diff
==============================================================================
--- 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;
 }
 


Reply via email to