Seleccionar un directorio con TOpenDialog


Realmente me gustaría saber las diversas formas en que podría seleccionar un directorio con el TOpenDialog, ya sea descargando un nuevo componente o usando lo que proporciona Delphi, pero preferiblemente usando lo que proporciona Delphi.

Antes de esto, he estado usando el comando SelectDirectory pero creo que sería una dificultad para los usuarios de mi programa buscar el directorio especificado.

Creo que el SelectDirectory es 'débil' porque puede ser un proceso largo al buscar el directorio que quieres. Digamos, por ejemplo, que desea navegar al directorio de datos de la aplicación. ¿Cuánto tiempo o difícil sería navegar allí? Al final, es posible que los usuarios ni siquiera lleguen a su directorio deseado.

Necesito algo como esto donde el usuario pueda copiar y pegar directorios en la barra de direcciones del directorio en la parte superior.

introduzca la descripción de la imagen aquí

Gracias por todas sus respuestas.

Author: ple103, 2011-09-15

5 answers

Puede utilizar el TFileOpenDialog (en Vista+):

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

Personalmente, siempre uso el {[2] } en Vista+ y el respaldo usando el SelectDirectory (¡el bueno!) en XP, así:

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)
 62
Author: Andreas Rejbrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-15 08:19:27

Sabes que las dos funciones sobrecargadas llamadas FileCtrl.SelectDirectory producen diálogos completamente diferentes, ¿verdad?

SelectDirectory(s, [], 0);

Captura de pantalla http://privat.rejbrand.se/oldseldir.png

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

Captura de pantalla http://privat.rejbrand.se/newseldir.png

 53
Author: Andreas Rejbrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-14 21:02:44

Acabo de encontrar el siguiente código que parece funcionar bien en XP y Vista, Win7. Proporciona una interfaz de usuario para que un usuario seleccione un directorio. Utiliza TOpenDialog, pero le envía algunos mensajes para limpiar la apariencia con el fin de seleccionar un directorio.

Después de sufrir de las capacidades limitadas proporcionadas por el propio Windows, es un placer poder dar a mis usuarios una interfaz de usuario familiar donde pueden navegar y seleccionar una carpeta cómodamente.

Había estado buscando algo como esto durante mucho tiempo, así que pensé en publicarlo aquí para que otros puedan beneficiarse de él.

Así es como se ve en Win 7:

captura de pantalla

//***********************
//** 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;
 6
Author: RobertFrank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-06 00:48:00

Solo incluye

FileCtrl.pas

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

Simplemente deje el segundo argumento vacío si desea ver todos los directorios incluyendo desktop. Si establece el segundo argumento en cualquier ruta válida, su diálogo tendrá esa ruta a la carpeta superior y no podrá navegar más allá de ella.

Por ejemplo:

SelectDirectory('Your caption','C:\',sDir) no te permitirá seleccionar nada más allá de C:\, como D:\ o E:\ etc.

Así que es bueno dejarlo vacío.

 6
Author: Shadab Mozaffar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-28 20:07:43

Si está utilizando JVCL puede utilizar TJvSelectDirectory. Con esto puede cambiar entre el estilo antiguo y el nuevo configurando una propiedad. Por ejemplo:

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; 
 2
Author: yonojoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-17 07:59:54