delphi - edition - Seleccionar un directorio con TOpenDialog
delphi versiones (5)
Acabo de encontrar el siguiente código que parece funcionar bien en XP y Vista, Win7. Proporciona una IU para que un usuario seleccione un directorio. Utiliza TOpenDialog, pero le envía algunos mensajes para limpiar la apariencia a fin de seleccionar un directorio.
Después de sufrir las capacidades limitadas proporcionadas por Windows, es un placer poder ofrecer a mis usuarios una interfaz de usuario familiar donde puedan buscar y seleccionar una carpeta cómodamente.
Había estado buscando algo así durante mucho tiempo, así que pensé en publicarlo aquí para que otros puedan beneficiarse de él.
Esto es lo que parece en Win 7:
//***********************
//** 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;
Realmente me gustaría saber las diversas formas en que podría seleccionar un directorio con TOpenDialog, ya sea descargando un nuevo componente o usando lo que proporciona Delphi, pero preferentemente 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 SelectDirectory es "débil" porque puede ser un proceso largo cuando busca el directorio que desea. Digamos, por ejemplo, que desea navegar al directorio de datos de la aplicación. ¿Qué tan largo 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.
Gracias por todas tus respuestas.
Puede usar TFileOpenDialog
(en Vista +):
with TFileOpenDialog.Create(nil) do
try
Options := [fdoPickFolders];
if Execute then
ShowMessage(FileName);
finally
Free;
end;
Personalmente, siempre uso el TFileOpenDialog
en Vista + y la SelectDirectory
utilizando 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)
Si está utilizando JVCL , puede usar TJvSelectDirectory. Con esto, puede cambiar entre el estilo antiguo y el nuevo estableciendo 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;
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, incluido el escritorio. Si establece un segundo argumento para cualquier ruta válida, su cuadro de diálogo tendrá esa ruta a la carpeta superior y no podrá navegar más allá de eso.
Por ejemplo:
SelectDirectory(''Your caption'',''C:/',sDir)
no te permitirá seleccionar nada más allá de C:/
, como D:/
o E:/
etc.
Entonces es bueno dejarlo vacío.
Usted sabe 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, []);