Selaa lähdekoodia

ADD: Abort shell operations

Alexander Koblov 2 vuotta sitten
vanhempi
commit
756d34e13b

+ 13 - 4
src/filesources/shellfolder/ushellcopyoperation.pas

@@ -62,7 +62,8 @@ type
 implementation
 
 uses
-  ActiveX, DCConvertEncoding, uFileSourceOperationUI, uShellFolder, uGlobs, uLog;
+  ActiveX, DCConvertEncoding, uFileSourceOperationUI, uShlObjAdditional,
+  uShellFolder, uGlobs, uLog;
 
 procedure TShellCopyOperation.ShowError(const sMessage: String);
 begin
@@ -137,11 +138,12 @@ end;
 
 procedure TShellCopyOperation.MainExecute;
 var
+  Res: HRESULT;
   dwCookie: DWORD;
   siItemArray: IShellItemArray;
   ASink: TFileOperationProgressSink;
 begin
-  ASink:= TFileOperationProgressSink.Create(@FStatistics, @UpdateStatistics);
+  ASink:= TFileOperationProgressSink.Create(@FStatistics, @UpdateStatistics, @CheckOperationStateSafe);
 
   FFileOp.SetOperationFlags(FOF_SILENT or FOF_NOCONFIRMMKDIR);
 
@@ -150,12 +152,19 @@ begin
     try
       OleCheck(SHCreateShellItemArrayFromIDLists(FSourceFilesTree.Count, PPItemIDList(FSourceFilesTree.List), siItemArray));
       OleCheck(FFileOp.CopyItems(siItemArray, FTargetFolder));
-      OleCheck(FFileOp.PerformOperations);
+      Res:= FFileOp.PerformOperations;
+      if Failed(Res) then
+      begin
+        if Res = COPYENGINE_E_USER_CANCELLED then
+          RaiseAbortOperation
+        else
+          OleError(Res);
+      end;
     finally
       FFileOp.Unadvise(dwCookie);
     end;
   except
-    on E: Exception do ShowError(E.Message);
+    on E: EOleError do ShowError(E.Message);
   end;
 end;
 

+ 12 - 4
src/filesources/shellfolder/ushelldeleteoperation.pas

@@ -41,7 +41,7 @@ type
 implementation
 
 uses
-  DCOSUtils, uLng, uShellFolder;
+  DCOSUtils, uLng, uShellFolder, uShlObjAdditional;
 
 procedure TShellDeleteOperation.ShowError(const sMessage: String);
 begin
@@ -95,11 +95,12 @@ end;
 
 procedure TShellDeleteOperation.MainExecute;
 var
+  Res: HRESULT;
   dwCookie: DWORD;
   siItemArray: IShellItemArray;
   ASink: TFileOperationProgressSink;
 begin
-  ASink:= TFileOperationProgressSink.Create(@FStatistics, @UpdateStatistics);
+  ASink:= TFileOperationProgressSink.Create(@FStatistics, @UpdateStatistics, @CheckOperationStateSafe);
 
   FFileOp.SetOperationFlags(FOF_SILENT or FOF_NOCONFIRMATION or FOF_NORECURSION);
   try
@@ -107,12 +108,19 @@ begin
     try
       OleCheck(SHCreateShellItemArrayFromIDLists(FSourceFilesTree.Count, PPItemIDList(FSourceFilesTree.List), siItemArray));
       OleCheck(FFileOp.DeleteItems(siItemArray));
-      OleCheck(FFileOp.PerformOperations);
+      Res:= FFileOp.PerformOperations;
+      if Failed(Res) then
+      begin
+        if Res = COPYENGINE_E_USER_CANCELLED then
+          RaiseAbortOperation
+        else
+          OleError(Res);
+      end;
     finally
       FFileOp.Unadvise(dwCookie);
     end;
   except
-    on E: Exception do ShowError(E.Message);
+    on E: EOleError do ShowError(E.Message);
   end;
 end;
 

+ 23 - 11
src/filesources/shellfolder/ushellfilesourceutil.pas

@@ -19,6 +19,7 @@ type
     destructor Destroy; override;
   end;
 
+  TCheckOperationState = function(): Boolean of object;
   TUpdateCopyStatisticsFunction = procedure(var NewStatistics: TFileSourceCopyOperationStatistics) of object;
   TUpdateDeleteStatisticsFunction = procedure(var NewStatistics: TFileSourceDeleteOperationStatistics) of object;
   TUpdateSetFilePropertyStatisticsFunction = procedure(var NewStatistics: TFileSourceSetFilePropertyOperationStatistics) of object;
@@ -27,6 +28,7 @@ type
 
   TFileOperationProgressSink = class(TInterfacedObject, IFileOperationProgressSink)
   private
+    FCheckOperationState: TCheckOperationState;
     FCopyStatistics: PFileSourceCopyOperationStatistics;
     FUpdateCopyStatistics: TUpdateCopyStatisticsFunction;
     FDeleteStatistics: PFileSourceDeleteOperationStatistics;
@@ -36,9 +38,9 @@ type
   protected
     procedure LogMessage(sMessage: String; logOptions: TLogOptions; logMsgType: TLogMsgType);
   public
-    constructor Create(AStatistics: PFileSourceCopyOperationStatistics; AUpdateStatistics: TUpdateCopyStatisticsFunction); reintroduce; overload;
-    constructor Create(AStatistics: PFileSourceDeleteOperationStatistics; AUpdateStatistics: TUpdateDeleteStatisticsFunction); reintroduce; overload;
-    constructor Create(AStatistics: PFileSourceSetFilePropertyOperationStatistics; AUpdateStatistics: TUpdateSetFilePropertyStatisticsFunction); reintroduce; overload;
+    constructor Create(AStatistics: PFileSourceCopyOperationStatistics; AUpdateStatistics: TUpdateCopyStatisticsFunction; ACheckOperationState: TCheckOperationState); reintroduce; overload;
+    constructor Create(AStatistics: PFileSourceDeleteOperationStatistics; AUpdateStatistics: TUpdateDeleteStatisticsFunction; ACheckOperationState: TCheckOperationState); reintroduce; overload;
+    constructor Create(AStatistics: PFileSourceSetFilePropertyOperationStatistics; AUpdateStatistics: TUpdateSetFilePropertyStatisticsFunction; ACheckOperationState: TCheckOperationState); reintroduce; overload;
   public
     function StartOperations: HResult; stdcall;
     function FinishOperations(hrResult: HResult): HResult; stdcall;
@@ -77,7 +79,7 @@ var
 implementation
 
 uses
-  DCOSUtils, DCConvertEncoding, uLng;
+  DCOSUtils, DCConvertEncoding, uShlObjAdditional, uLng;
 
 var
   AModule: HMODULE;
@@ -117,26 +119,32 @@ end;
 
 constructor TFileOperationProgressSink.Create(
   AStatistics: PFileSourceCopyOperationStatistics;
-  AUpdateStatistics: TUpdateCopyStatisticsFunction);
+  AUpdateStatistics: TUpdateCopyStatisticsFunction;
+  ACheckOperationState: TCheckOperationState);
 begin
   FCopyStatistics:= AStatistics;
   FUpdateCopyStatistics:= AUpdateStatistics;
+  FCheckOperationState:= ACheckOperationState;
 end;
 
 constructor TFileOperationProgressSink.Create(
   AStatistics: PFileSourceDeleteOperationStatistics;
-  AUpdateStatistics: TUpdateDeleteStatisticsFunction);
+  AUpdateStatistics: TUpdateDeleteStatisticsFunction;
+  ACheckOperationState: TCheckOperationState);
 begin
   FDeleteStatistics:= AStatistics;
   FUpdateDeleteStatistics:= AUpdateStatistics;
+  FCheckOperationState:= ACheckOperationState;
 end;
 
 constructor TFileOperationProgressSink.Create(
   AStatistics: PFileSourceSetFilePropertyOperationStatistics;
-  AUpdateStatistics: TUpdateSetFilePropertyStatisticsFunction);
+  AUpdateStatistics: TUpdateSetFilePropertyStatisticsFunction;
+  ACheckOperationState: TCheckOperationState);
 begin
   FSetFilePropertyStatistics:= AStatistics;
   FUpdateSetFilePropertyStatistics:= AUpdateStatistics;
+  FCheckOperationState:= ACheckOperationState;
 end;
 
 function TFileOperationProgressSink.StartOperations: HResult; stdcall;
@@ -181,7 +189,7 @@ function TFileOperationProgressSink.PostMoveItem(dwFlags: DWORD;
   psiItem: IShellItem; psiDestinationFolder: IShellItem; pszNewName: LPCWSTR;
   hrMove: HRESULT; psiNewlyCreated: IShellItem): HResult; stdcall;
 begin
-  if (log_cp_mv_ln in gLogOptions) then
+  if (log_cp_mv_ln in gLogOptions) and (hrMove <> COPYENGINE_E_USER_CANCELLED) then
   begin
     with FCopyStatistics^ do
     begin
@@ -232,7 +240,7 @@ function TFileOperationProgressSink.PostCopyItem(dwFlags: DWORD;
   psiItem: IShellItem; psiDestinationFolder: IShellItem; pszNewName: LPCWSTR;
   hrCopy: HRESULT; psiNewlyCreated: IShellItem): HResult; stdcall;
 begin
-  if (log_cp_mv_ln in gLogOptions) then
+  if (log_cp_mv_ln in gLogOptions) and (hrCopy <> COPYENGINE_E_USER_CANCELLED) then
   begin
     with FCopyStatistics^ do
     begin
@@ -270,7 +278,7 @@ var
   AText: String;
   sfgaoAttribs: SFGAOF = 0;
 begin
-  if log_delete in gLogOptions then
+  if (log_delete in gLogOptions) and (hrDelete <> COPYENGINE_E_USER_CANCELLED) then
   begin
     psiItem.GetAttributes(SFGAO_FOLDER, @sfgaoAttribs);
     if (sfgaoAttribs and SFGAO_FOLDER) = 0 then
@@ -333,7 +341,11 @@ begin
     FUpdateSetFilePropertyStatistics(FSetFilePropertyStatistics^);
   end;
 
-  Result:= S_OK;
+  if FCheckOperationState() then
+    Result:= S_OK
+  else begin
+    Result:= COPYENGINE_E_USER_CANCELLED;
+  end;
 end;
 
 function TFileOperationProgressSink.ResetTimer: HResult; stdcall;

+ 12 - 4
src/filesources/shellfolder/ushellmoveoperation.pas

@@ -46,7 +46,7 @@ implementation
 
 uses
   uFileSourceOperationOptions, uFileSourceOperationUI, uShellFolder, uGlobs,
-  uLog, uLng;
+  uShlObjAdditional, uLog, uLng;
 
 procedure TShellMoveOperation.ShowError(const sMessage: String);
 begin
@@ -107,11 +107,12 @@ end;
 
 procedure TShellMoveOperation.MainExecute;
 var
+  Res: HRESULT;
   dwCookie: DWORD;
   siItemArray: IShellItemArray;
   ASink: TFileOperationProgressSink;
 begin
-  ASink:= TFileOperationProgressSink.Create(@FStatistics, @UpdateStatistics);
+  ASink:= TFileOperationProgressSink.Create(@FStatistics, @UpdateStatistics, @CheckOperationStateSafe);
 
   FFileOp.SetOperationFlags(FOF_SILENT or FOF_NOCONFIRMMKDIR);
 
@@ -120,12 +121,19 @@ begin
     try
       OleCheck(SHCreateShellItemArrayFromIDLists(FSourceFilesTree.Count, PPItemIDList(FSourceFilesTree.List), siItemArray));
       OleCheck(FFileOp.MoveItems(siItemArray, FTargetFolder));
-      OleCheck(FFileOp.PerformOperations);
+      Res:= FFileOp.PerformOperations;
+      if Failed(Res) then
+      begin
+        if Res = COPYENGINE_E_USER_CANCELLED then
+          RaiseAbortOperation
+        else
+          OleError(Res);
+      end;
     finally
       FFileOp.Unadvise(dwCookie);
     end;
   except
-    on E: Exception do ShowError(E.Message);
+    on E: EOleError do ShowError(E.Message);
   end;
 end;
 

+ 13 - 4
src/filesources/shellfolder/ushellsetfilepropertyoperation.pas

@@ -46,7 +46,7 @@ type
 implementation
 
 uses
-  Windows, ActiveX, ShlObj, ComObj, DCConvertEncoding,
+  Windows, ActiveX, ShlObj, ComObj, DCConvertEncoding, uShlObjAdditional,
   uFileSourceOperationUI, uShellFolder, uGlobs, uLog, uLng;
 
 procedure TShellSetFilePropertyOperation.ShowError(const sMessage: String);
@@ -111,7 +111,7 @@ var
   CurrentFileIndex: Integer;
   ASink: TFileOperationProgressSink;
 begin
-  ASink:= TFileOperationProgressSink.Create(@FStatistics, @UpdateStatistics);
+  ASink:= TFileOperationProgressSink.Create(@FStatistics, @UpdateStatistics, @CheckOperationStateSafe);
 
   FFileOp.SetOperationFlags(FOF_SILENT or FOF_NOCONFIRMMKDIR);
 
@@ -144,6 +144,7 @@ end;
 function TShellSetFilePropertyOperation.SetNewProperty(aFile: TFile;
                                                        aTemplateProperty: TFileProperty): TSetFilePropertyResult;
 var
+  Res: HRESULT;
   PIDL: PItemIDList;
   AItem: IShellItem;
 begin
@@ -161,8 +162,16 @@ begin
         begin
           if not Succeeded(FFileOp.RenameItem(AItem, PWideChar(CeUtf8ToUtf16((aTemplateProperty as TFileNameProperty).Value)), nil)) then
             Result := sfprError
-          else if not Succeeded(FFileOp.PerformOperations()) then
-            Result := sfprError
+          else begin
+            Res:= FFileOp.PerformOperations();
+            if Failed(Res) then
+            begin
+              if Res = COPYENGINE_E_USER_CANCELLED then
+                RaiseAbortOperation
+              else
+                Result := sfprError
+            end;
+          end;
         end
         else
           Result := sfprSkipped;