SHFileOperation - add ChangeNotify events

Vitaliy Margolen wine-patch at kievinfo.com
Sat Mar 8 19:27:07 CST 2003


This patch adds correct calls to SHChangeNotify on every operation in SHFileOperation.
It also treats FOF_NOCONFIRMATION flag properly. Actually absence of this flag.

Vitaliy Margolen

changelog:
  dlls/shell32/shlfileop.c
  * add calls to SHChangeNotify for all operations
  * show confirmation dialogs if FOF_NOCONFIRMATION is not set



Index: dlls/shell32/shlfileop.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shlfileop.c,v
retrieving revision 1.24
diff -u -r1.24 shlfileop.c
--- dlls/shell32/shlfileop.c    1 Feb 2003 00:41:30 -0000       1.24
+++ dlls/shell32/shlfileop.c    9 Mar 2003 01:03:08 -0000
@@ -72,6 +72,49 @@
        return (IDOK == MessageBoxA(GetActiveWindow(), szBuffer, szCaption, MB_OKCANCEL | MB_ICONEXCLAMATION));
 }
 
+/************************************************************************
+ * Win32DeleteFile                         [SHELL32.164]
+ *
+ * Deletes a file. Also triggers a change notify if one exists.
+ *
+ * NOTES:
+ *  Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
+ *  This is Unicode on NT/2000
+ */
+static BOOL Win32DeleteFileA(LPCSTR fName)
+{
+       LPITEMIDLIST    Pidls[1];
+       DWORD           dummy;
+
+       TRACE("%p(%s)\n", fName, fName);
+
+        SHILCreateFromPathA(fName, &Pidls[0], &dummy);
+       DeleteFileA(fName);
+       SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, Pidls[0], NULL);
+        SHFree(Pidls[0]);
+       return TRUE;
+}
+
+static BOOL Win32DeleteFileW(LPCWSTR fName)
+{
+       LPITEMIDLIST    Pidls[1];
+       DWORD           dummy;
+
+       TRACE("%p(%s)\n", fName, debugstr_w(fName));
+
+        SHILCreateFromPathW(fName, &Pidls[0], &dummy);
+       DeleteFileW(fName);
+       SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, Pidls[0], NULL);
+       return TRUE;
+}
+
+DWORD WINAPI Win32DeleteFileAW(LPCVOID fName)
+{
+       if (SHELL_OsIsUnicode())
+         return Win32DeleteFileW(fName);
+       return Win32DeleteFileA(fName);
+}
+
 /**************************************************************************
  *     SHELL_DeleteDirectoryA()
  *
@@ -84,6 +127,8 @@
        HANDLE          hFind;
        WIN32_FIND_DATAA wfd;
        char            szTemp[MAX_PATH];
+       LPITEMIDLIST    Pidls[1];
+       DWORD           dummy;
 
        strcpy(szTemp, pszDir);
        PathAddBackslashA(szTemp);
@@ -103,14 +148,18 @@
              strcat(szTemp, wfd.cFileName);
 
              if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
-               SHELL_DeleteDirectoryA(szTemp, FALSE);
+               SHELL_DeleteDirectoryA(szTemp, bShowUI);
              else
-               DeleteFileA(szTemp);
+               Win32DeleteFileA((LPCSTR)szTemp);
            }
          } while(FindNextFileA(hFind, &wfd));
 
          FindClose(hFind);
+          SHILCreateFromPathA(pszDir, &Pidls[0], &dummy);
          ret = RemoveDirectoryA(pszDir);
+         if (ret)
+            SHChangeNotify(SHCNE_RMDIR, SHCNF_IDLIST, Pidls[0], NULL);
+          SHFree(Pidls[0]);
        }
 
        return ret;
@@ -122,10 +171,19 @@
 
 BOOL SHELL_DeleteFileA(LPCSTR pszFile, BOOL bShowUI)
 {
+        BOOL ret;
+        LPITEMIDLIST    Pidls[1];
+        DWORD           dummy;
+        
        if (bShowUI && !SHELL_ConfirmDialog(ASK_DELETE_FILE, pszFile))
                return FALSE;
 
-        return DeleteFileA(pszFile);
+        SHILCreateFromPathA(pszFile, &Pidls[0], &dummy);
+        ret = DeleteFileA(pszFile);
+       if (ret)
+           SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, Pidls[0], NULL);
+        SHFree(Pidls[0]);
+       return ret;
 }
 
 /*************************************************************************
@@ -174,40 +232,6 @@
        return ret;
 }
 
-/************************************************************************
- * Win32DeleteFile                         [SHELL32.164]
- *
- * Deletes a file. Also triggers a change notify if one exists.
- *
- * NOTES:
- *  Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
- *  This is Unicode on NT/2000
- */
-static BOOL Win32DeleteFileA(LPCSTR fName)
-{
-       TRACE("%p(%s)\n", fName, fName);
-
-       DeleteFileA(fName);
-       SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, fName, NULL);
-       return TRUE;
-}
-
-static BOOL Win32DeleteFileW(LPCWSTR fName)
-{
-       TRACE("%p(%s)\n", fName, debugstr_w(fName));
-
-       DeleteFileW(fName);
-       SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW, fName, NULL);
-       return TRUE;
-}
-
-DWORD WINAPI Win32DeleteFileAW(LPCVOID fName)
-{
-       if (SHELL_OsIsUnicode())
-         return Win32DeleteFileW(fName);
-       return Win32DeleteFileA(fName);
-}
-
 /**************************************************************************
  *     SHELL_FileNamesMatch()
  *
@@ -241,6 +265,7 @@
        LPSTR pFrom = (LPSTR)lpFileOp->pFrom;
        LPSTR pTo = (LPSTR)lpFileOp->pTo;
        LPSTR pTempTo;
+
         TRACE("flags (0x%04x) : %s%s%s%s%s%s%s%s%s%s%s%s \n", lpFileOp->fFlags,
                 lpFileOp->fFlags & FOF_MULTIDESTFILES ? "FOF_MULTIDESTFILES " : "",
                 lpFileOp->fFlags & FOF_CONFIRMMOUSE ? "FOF_CONFIRMMOUSE " : "",
@@ -277,6 +302,8 @@
                 int multifrom = pFrom[strlen(pFrom) + 1] != '\0';
                 int destisdir = PathIsDirectoryA( pTo );
                 int todir = 0;
+                LPITEMIDLIST    Pidls[1];
+                DWORD           dummy;
 
                 if (lpFileOp->wFunc == FO_COPY)
                     TRACE("File Copy:\n");
@@ -366,12 +393,18 @@
                                           }
                                       }
                                       else
-                                          CopyFileA(szTempFrom, pTempTo, FALSE);
+                                          if (CopyFileA(szTempFrom, pTempTo, FALSE))
+                                              SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, pTempTo, NULL);
                                   }
                                   else
                                   {
+                                      SHILCreateFromPathA(szTempFrom, &Pidls[0], &dummy);
                                       /* move file/directory */
-                                      MoveFileA(szTempFrom, pTempTo);
+                                      if (MoveFileA(szTempFrom, pTempTo)){
+                                          SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, pTempTo, NULL);
+                                          SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, szTempFrom, NULL);
+                                      }
+                                      SHFree(Pidls[0]);
                                   }
                                   HeapFree(GetProcessHeap(), 0, pTempTo);
                               }
@@ -402,9 +435,20 @@
                                 HeapFree(GetProcessHeap(), 0, pTempTo);
                             }
                             if (lpFileOp->wFunc == FO_COPY)
-                                CopyFileA(pFrom, pTo, FALSE);
+                            {
+                                if (CopyFileA(pFrom, pTo, FALSE))
+                                    SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, pTo, NULL);
+                            }
                             else
-                                MoveFileA(pFrom, pTo);
+                            {
+                                SHILCreateFromPathA(pFrom, &Pidls[0], &dummy);
+                                if (MoveFileA(pFrom, pTo))
+                                {
+                                    SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, &Pidls[0], NULL);
+                                    SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, pTo, NULL);
+                                }
+                                SHFree(Pidls[0]);
+                            }
 
                             pFrom += strlen(pFrom) + 1;
                             pTo += strlen(pTo) + 1;
@@ -442,10 +486,10 @@
                              if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
                              {
                                if(!(lpFileOp->fFlags & FOF_FILESONLY))
-                                   SHELL_DeleteDirectoryA(szTemp, FALSE);
+                                   SHELL_DeleteDirectoryA(szTemp, !(lpFileOp->fFlags & FOF_NOCONFIRMATION));
                              }
                              else
-                               DeleteFileA(szTemp);
+                               SHELL_DeleteFileA(szTemp, !(lpFileOp->fFlags & FOF_NOCONFIRMATION));
                            }
                          } while(FindNextFileA(hFind, &wfd));
 
@@ -459,6 +503,11 @@
        }
 
         case FO_RENAME:
+        {
+            LPITEMIDLIST    Pidls[2];
+            DWORD           dummy;
+            DWORD           ret;
+
             TRACE("File Rename:\n");
             if (pFrom[strlen(pFrom) + 1] != '\0')
             {
@@ -467,7 +516,18 @@
             }
             lpFileOp->fAnyOperationsAborted = FALSE;
             TRACE("From %s, To %s\n", pFrom, pTo);
-            return !MoveFileA(pFrom, pTo);
+            
+            SHILCreateFromPathA(pFrom, &Pidls[0], &dummy);
+            ret = MoveFileA(pFrom, pTo);
+            if (ret)
+            {
+                SHILCreateFromPathA(pTo, &Pidls[1], &dummy);
+                SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_IDLIST, &Pidls[0], &Pidls[1]);
+                SHFree(Pidls[1]);
+            }
+            SHFree(Pidls[0]);
+            return !ret;
+        }
 
        default:
                FIXME("Unhandled shell file operation %d\n", lpFileOp->wFunc);




More information about the wine-patches mailing list