Выбор каталога с TOpenDialog - PullRequest
       11

Выбор каталога с TOpenDialog

46 голосов
/ 15 сентября 2011

Мне бы очень хотелось узнать, как я могу выбрать каталог с помощью TOpenDialog, будь то загрузка нового компонента или использование того, что предоставлено Delphi, но предпочтительно использование того, что предоставлено Delphi.

До этого я использовал команду SelectDirectory, но я думаю, что пользователям моей программы будет трудно найти указанный каталог.

Я думаю, что SelectDirectory является «слабым», потому что он может занять много времени при поиске нужного каталога. Например, вы хотите перейти в каталог Application Data. Как долго или сложно будет там перемещаться? В конце концов, пользователи могут даже не достичь своего желаемого каталога.

Мне нужно что-то вроде этого, где пользователь может копировать и вставлять каталоги в адресную строку каталога там вверху.

enter image description here

Спасибо за все ваши ответы.

Ответы [ 5 ]

64 голосов
/ 15 сентября 2011

Вы можете использовать TFileOpenDialog (в Vista +):

with TFileOpenDialog.Create(nil) do
  try
    Options := [fdoPickFolders];
    if Execute then
      ShowMessage(FileName);
  finally
    Free;
  end;

Лично я всегда использую TFileOpenDialog на Vista + и откат, используя SelectDirectory (хороший!) На XP, например:

if Win32MajorVersion >= 6 then
  with TFileOpenDialog.Create(nil) do
    try
      Title := 'Select Directory';
      Options := [fdoPickFolders, fdoPathMustExist, fdoForceFileSystem]; // YMMV
      OkButtonLabel := 'Select';
      DefaultFolder := FDir;
      FileName := FDir;
      if Execute then
        ShowMessage(FileName);
    finally
      Free;
    end
else
  if SelectDirectory('Select Directory', ExtractFileDrive(FDir), FDir,
             [sdNewUI, sdNewFolder]) then
    ShowMessage(FDir)
56 голосов
/ 15 сентября 2011

Вы знаете, что две перегруженные функции, называемые FileCtrl.SelectDirectory, создают совершенно разные диалоги, верно?

SelectDirectory(s, [], 0);

Снимок экрана http://privat.rejbrand.se/oldseldir.png

SelectDirectory('Select a directory', s, s, []);

Снимок экрана http://privat.rejbrand.se/newseldir.png

6 голосов
/ 28 ноября 2016

Просто включите

FileCtrl.pas

var
  sDir:String;
begin
  SelectDirectory('Your caption','',sDir);
end;

Просто оставьте второй аргумент пустым, если хотите увидеть все каталоги, включая рабочий стол. Если для второго аргумента задан какой-либо допустимый путь, то в вашем диалоговом окне будет указан этот путь к верхней папке, и вы не сможете перейти за пределы этого.

Например:

SelectDirectory('Your caption','C:\',sDir) не позволит вам выбрать ничего, кроме C:\, например D:\ или E:\ и т. Д.

Так что хорошо бы оставить его пустым.

6 голосов
/ 05 сентября 2013

Только что нашел код ниже, который, кажется, отлично работает в XP и Vista, Win7.Он предоставляет пользовательский интерфейс для выбора каталога.Он использует TOpenDialog, но отправляет ему несколько сообщений, чтобы очистить внешний вид для целей выбора каталога.

После страданий от ограниченных возможностей, предоставляемых самой Windows, очень приятно быть в состоянии дать моим пользователямзнакомый пользовательский интерфейс, где они могут удобно просматривать и выбирать папку .

Я давно искал что-то подобное, поэтому подумал, что я опубликую это здесь, чтобы другие могли получить пользуот него.

Вот как это выглядит в Win 7:

screen capture

//***********************
//** Choose a directory **
//**   uses Messages   **
//***********************
  //General usage here:
  //  http://www.delphipages.com/forum/showthread.php?p=185734
  //Need a class to hold a procedure to be called by Dialog.OnShow:
  type TOpenDir = class(TObject)
  public
    Dialog: TOpenDialog;
    procedure HideControls(Sender: TObject);
  end;
  //This procedure hides de combo box of file types...
  procedure TOpenDir.HideControls(Sender: TObject);
  const
    //CDM_HIDECONTROL and CDM_SETCONTROLTEXT values from:
    //  doc.ddart.net/msdn/header/include/commdlg.h.html
    //  CMD_HIDECONTROL = CMD_FIRST + 5 = (WM_USER + 100) + 5;
    //Usage of CDM_HIDECONTROL and CDM_SETCONTROLTEXT here:
    //  msdn.microsoft.com/en-us/library/ms646853%28VS.85%29.aspx
    //  msdn.microsoft.com/en-us/library/ms646855%28VS.85%29.aspx
    CDM_HIDECONTROL =    WM_USER + 100 + 5;
    CDM_SETCONTROLTEXT = WM_USER + 100 + 4;
    //Component IDs from:
    //  msdn.microsoft.com/en-us/library/ms646960%28VS.85%29.aspx#_win32_Open_and_Save_As_Dialog_Box_Customization
    //Translation into exadecimal in dlgs.h:
    //  www.koders.com/c/fidCD2C946367FEE401460B8A91A3DB62F7D9CE3244.aspx
    //
    //File type filter...
    cmb1: integer  = $470; //Combo box with list of file type filters
    stc2: integer  = $441; //Label of the file type
    //File name const...
    cmb13: integer = $47c; //Combo box with name of the current file
    edt1: integer  = $480; //Edit with the name of the current file
    stc3: integer  = $442; //Label of the file name combo
  var H: THandle;
  begin
    H:= GetParent(Dialog.Handle);
    //Hide file types combo...
    SendMessage(H, CDM_HIDECONTROL, cmb1,  0);
    SendMessage(H, CDM_HIDECONTROL, stc2,  0);
    //Hide file name label, edit and combo...
    SendMessage(H, CDM_HIDECONTROL, cmb13, 0);
    SendMessage(H, CDM_HIDECONTROL, edt1,  0);
    SendMessage(H, CDM_HIDECONTROL, stc3,  0);
    //NOTE: How to change label text (the lentgh is not auto):
    //SendMessage(H, CDM_SETCONTROLTEXT, stc3, DWORD(pChar('Hello!')));
  end;
//Call it when you need the user to chose a folder for you...
function GimmeDir(var Dir: string): boolean;
var
  OpenDialog: TOpenDialog;
  OpenDir: TOpenDir;
begin
  //The standard dialog...
  OpenDialog:= TOpenDialog.Create(nil);
  //Objetc that holds the OnShow code to hide controls
  OpenDir:= TOpenDir.create;
  try
    //Conect both components...
    OpenDir.Dialog:= OpenDialog;
    OpenDialog.OnShow:= OpenDir.HideControls;
    //Configure it so only folders are shown (and file without extension!)...
    OpenDialog.FileName:= '*.';
    OpenDialog.Filter:=   '*.';
    OpenDialog.Title:=    'Chose a folder';
    //No need to check file existis!
    OpenDialog.Options:= OpenDialog.Options + [ofNoValidate];
    //Initial folder...
    OpenDialog.InitialDir:= Dir;
    //Ask user...
    if OpenDialog.Execute then begin
      Dir:= ExtractFilePath(OpenDialog.FileName);
      result:= true;
    end else begin
      result:= false;
    end;
  finally
    //Clean up...
    OpenDir.Free;
    OpenDialog.Free;
  end;
end;
2 голосов
/ 17 июля 2015

Если вы используете JVCL , вы можете использовать TJvSelectDirectory. При этом вы можете переключаться между старым и новым стилем, устанавливая свойство. Например:

Dlg := TJvSelectDirectory.Create(Self);
try
    Dlg.Title := MyTitle;
    Dlg.InitialDir := MyStartDir;
    Dlg.Options := Dlg.Options + [sdAllowCreate, sdPerformCreate];     
    Dlg.ClassicDialog := False;   //switch style
    if Dlg.Execute() then
      NewDir := Dlg.Directory;
finally
    Dlg.Free;
end; 
...