Browse Source

FIX: Call internal commands from context menu asynchronously (Windows)

Alexander Koblov 4 years ago
parent
commit
71620710ab
1 changed files with 32 additions and 25 deletions
  1. 32 25
      src/platform/win/ushellcontextmenu.pas

+ 32 - 25
src/platform/win/ushellcontextmenu.pas

@@ -61,6 +61,8 @@ type
     FShellMenu1: IContextMenu;
     FShellMenu1: IContextMenu;
     FShellMenu: HMENU;
     FShellMenu: HMENU;
     FUserWishForContextMenu: TUserWishForContextMenu;
     FUserWishForContextMenu: TUserWishForContextMenu;
+  protected
+    procedure Execute(Data: PtrInt);
   public
   public
     constructor Create(Parent: TWinControl; var Files: TFiles; Background: boolean; UserWishForContextMenu: TUserWishForContextMenu = uwcmComplete); reintroduce;
     constructor Create(Parent: TWinControl; var Files: TFiles; Background: boolean; UserWishForContextMenu: TUserWishForContextMenu = uwcmComplete); reintroduce;
     destructor Destroy; override;
     destructor Destroy; override;
@@ -76,7 +78,8 @@ implementation
 uses
 uses
   graphtype, intfgraphics, Graphics, uPixMapManager, Dialogs, uLng, uMyWindows,
   graphtype, intfgraphics, Graphics, uPixMapManager, Dialogs, uLng, uMyWindows,
   uShellExecute, fMain, uDCUtils, uFormCommands, DCOSUtils, uOSUtils, uShowMsg,
   uShellExecute, fMain, uDCUtils, uFormCommands, DCOSUtils, uOSUtils, uShowMsg,
-  uExts, uFileSystemFileSource, DCConvertEncoding, LazUTF8, uOSForms, uGraphics;
+  uExts, uFileSystemFileSource, DCConvertEncoding, LazUTF8, uOSForms, uGraphics,
+  Forms;
 
 
 const
 const
   USER_CMD_ID = $1000;
   USER_CMD_ID = $1000;
@@ -476,6 +479,28 @@ end;
 
 
 { TShellContextMenu }
 { TShellContextMenu }
 
 
+procedure TShellContextMenu.Execute(Data: PtrInt);
+var
+  UserSelectedCommand: TExtActionCommand absolute Data;
+begin
+  try
+    with frmMain.ActiveFrame do
+    begin
+      try
+        //For the %-Variable replacement that follows it might sounds incorrect to do it with "nil" instead of "aFile",
+        //but original code was like that. It is useful, at least, when more than one file is selected so because of that,
+        //it's pertinent and should be kept!
+        ProcessExtCommandFork(UserSelectedCommand.CommandName, UserSelectedCommand.Params, UserSelectedCommand.StartPath, nil);
+      except
+        on e: EInvalidCommandLine do
+          MessageDlg(rsMsgErrorInContextMenuCommand, rsMsgInvalidCommandLine + ': ' + e.Message, mtError, [mbOK], 0);
+      end;
+    end;
+  finally
+    FreeAndNil(UserSelectedCommand);
+  end;
+end;
+
 { TShellContextMenu.Create }
 { TShellContextMenu.Create }
 constructor TShellContextMenu.Create(Parent: TWinControl; var Files: TFiles; Background: boolean; UserWishForContextMenu: TUserWishForContextMenu);
 constructor TShellContextMenu.Create(Parent: TWinControl; var Files: TFiles; Background: boolean; UserWishForContextMenu: TUserWishForContextMenu);
 var
 var
@@ -737,33 +762,15 @@ begin
         end
         end
         else
         else
         begin
         begin
-          try
-            with frmMain.ActiveFrame do
-            begin
-              try
-                //For the %-Variable replacement that follows it might sounds incorrect to do it with "nil" instead of "aFile",
-                //but original code was like that. It is useful, at least, when more than one file is selected so because of that,
-                //it's pertinent and should be kept!
-                ProcessExtCommandFork(UserSelectedCommand.CommandName, UserSelectedCommand.Params, UserSelectedCommand.StartPath, nil);
-              except
-                on e: EInvalidCommandLine do
-                  MessageDlg(rsMsgErrorInContextMenuCommand, rsMsgInvalidCommandLine + ': ' + e.Message, mtError, [mbOK], 0);
-              end;
-            end;
-          finally
-            bHandled := True;
-          end;
+          Application.QueueAsyncCall(Execute, PtrInt(UserSelectedCommand));
+          UserSelectedCommand := nil;
+          bHandled := True;
         end;
         end;
       end;
       end;
     finally
     finally
-      if Assigned(InnerExtActionList) then
-        FreeAndNil(InnerExtActionList);
-
-      if Assigned(UserSelectedCommand) then
-        FreeAndNil(UserSelectedCommand);
-
-      if Assigned(ContextMenuDCIcon) then
-        FreeAndNil(ContextMenuDCIcon);
+      FreeAndNil(InnerExtActionList);
+      FreeAndNil(UserSelectedCommand);
+      FreeAndNil(ContextMenuDCIcon);
     end;
     end;
 
 
   except
   except