瀏覽代碼

Using modern directory selection dialog that scales correctly (Issue 2373) and allows creating new directory (Issue 2389)

https://winscp.net/tracker/2373
https://winscp.net/tracker/2389

Source commit: 588f914125bc47c206b193ec8410b4babc0dcd6f
Martin Prikryl 4 月之前
父節點
當前提交
ca34927d67
共有 4 個文件被更改,包括 27 次插入52 次删除
  1. 1 0
      source/forms/CopyLocal.cpp
  2. 25 27
      source/packages/my/ComboEdit.pas
  3. 1 24
      source/windows/VCLCommon.cpp
  4. 0 1
      source/windows/VCLCommon.h

+ 1 - 0
source/forms/CopyLocal.cpp

@@ -9,6 +9,7 @@
 #include "GUITools.h"
 #include "Tools.h"
 #include "WinInterface.h"
+#include "ComboEdit.hpp"
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 #pragma link "HistoryComboBox"

+ 25 - 27
source/packages/my/ComboEdit.pas

@@ -142,7 +142,6 @@ type
 
   TFileDirEdit = class(TCustomComboEdit)
   private
-    FErrMode: Cardinal;
     FAcceptFiles: Boolean;
     FOnBeforeDialog: TExecOpenDialogEvent;
     FOnAfterDialog: TExecOpenDialogEvent;
@@ -156,8 +155,6 @@ type
     procedure DoBeforeDialog(var FileName: string; var Action: Boolean); dynamic;
     procedure ReceptFileDir(const AFileName: string); virtual; abstract;
     procedure ClearFileList; virtual;
-    procedure DisableSysErrors;
-    procedure EnableSysErrors;
     property MaxLength;
   published
     property AcceptFiles: Boolean read FAcceptFiles write SetAcceptFiles default False;
@@ -341,16 +338,36 @@ type
 
 procedure Register;
 
+function SelectDirectory(var Directory: string; Prompt: string): Boolean;
+
 implementation
 
 uses
-  ShellAPI, Consts, ExtDlgs, Variants, PasTools, UITypes;
+  ShellAPI, Consts, ExtDlgs, Variants, PasTools, UITypes, StrUtils;
 
 procedure Register;
 begin
   RegisterComponents('Martin', [TComboEdit, TFilenameEdit, TDirectoryEdit]);
 end;
 
+function SelectDirectory(var Directory: string; Prompt: string): Boolean;
+var
+  Folders: TArray<string>;
+begin
+  // Prompt was originally used with old-style SHBrowseForFolder directory browsing dialog,
+  // where it is displayed as instructions on a label. Hence it had a dot at the end.
+  // Now it is used in window title, so we are removing the trailing dot.
+  if EndsStr('.', Prompt) then
+    SetLength(Prompt, Length(Prompt) - 1);
+
+  Folders := [];
+  Result :=
+    FileCtrl.SelectDirectory(Directory, Folders, [], Prompt) and
+    (Length(Folders) > 0);
+  if Result then
+    Directory := Folders[0];
+end;
+
 { Utility functions }
 
 function ValidFileName(const FileName: string): Boolean;
@@ -665,17 +682,6 @@ begin
   end;
 end;
 
-procedure TFileDirEdit.DisableSysErrors;
-begin
-  FErrMode := SetErrorMode(SEM_NOOPENFILEERRORBOX or SEM_FAILCRITICALERRORS);
-end;
-
-procedure TFileDirEdit.EnableSysErrors;
-begin
-  SetErrorMode(FErrMode);
-  FErrMode := 0;
-end;
-
 procedure TFileDirEdit.WMDropFiles(var Msg: TWMDropFiles);
 var
   AFileName: array[0..255] of Char;
@@ -866,12 +872,7 @@ begin
       { ignore any exceptions }
     end;
   FDialog.HelpContext := Self.HelpContext;
-  DisableSysErrors;
-  try
-    Action := FDialog.Execute;
-  finally
-    EnableSysErrors;
-  end;
+  Action := FDialog.Execute;
   if Action then Temp := FDialog.FileName;
   if CanFocus then SetFocus;
   DoAfterDialog(Temp, Action);
@@ -1024,12 +1025,9 @@ begin
     else Temp := '\';
   end;
   if not DirectoryExists(Temp) then Temp := '\';
-  DisableSysErrors;
-  try
-    Action := SelectDirectory(FDialogText, '', Temp);
-  finally
-    EnableSysErrors;
-  end;
+
+  Action := SelectDirectory(Temp, FDialogText);
+
   if CanFocus then SetFocus;
   DoAfterDialog(Temp, Action);
   if Action then

+ 1 - 24
source/windows/VCLCommon.cpp

@@ -26,6 +26,7 @@
 #include <UpDownEdit.hpp>
 #include <WinApi.h>
 #include <vssym32.h>
+#include <ComboEdit.hpp>
 //---------------------------------------------------------------------------
 const UnicodeString ContextSeparator(TraceInitStr(L"\x00BB"));
 const UnicodeString LinkAppLabelMark(TraceInitStr(UnicodeString(L" ") + ContextSeparator));
@@ -1356,30 +1357,6 @@ bool __fastcall ReleaseAsModal(TForm * Form, void *& Storage)
   return Result;
 }
 //---------------------------------------------------------------------------
-bool SelectDirectory(UnicodeString & ADirectory, const UnicodeString & Prompt)
-{
-  bool Result;
-  unsigned int ErrorMode;
-  ErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
-
-  try
-  {
-    UnicodeString Directory = ADirectory;
-    TSelectDirExtOpts Opts = TSelectDirExtOpts() << sdNewUI;
-    Result = SelectDirectory(Prompt, EmptyStr, Directory, Opts);
-    if (Result)
-    {
-      ADirectory = Directory;
-    }
-  }
-  __finally
-  {
-    SetErrorMode(ErrorMode);
-  }
-
-  return Result;
-}
-//---------------------------------------------------------------------------
 void SelectDirectoryForEdit(THistoryComboBox * Edit)
 {
   UnicodeString OriginalDirectory = ExpandEnvironmentVariables(Edit->Text);

+ 0 - 1
source/windows/VCLCommon.h

@@ -44,7 +44,6 @@ void __fastcall ShowAsModal(TForm * Form, void *& Storage, bool BringToFront = t
 void __fastcall HideAsModal(TForm * Form, void *& Storage);
 bool __fastcall ReleaseAsModal(TForm * Form, void *& Storage);
 bool __fastcall IsMainFormLike(TCustomForm * Form);
-bool SelectDirectory(UnicodeString & Path, const UnicodeString & Prompt);
 void SelectDirectoryForEdit(THistoryComboBox * Edit);
 enum TListViewCheckAll { caCheck, caUncheck, caToggle };
 bool __fastcall ListViewAnyChecked(TListView * ListView, bool Checked = true);