61 votes

Sélection d'un répertoire avec TOpenDialog

J'aimerais vraiment connaître les différentes façons de sélectionner un répertoire avec le TOpenDialog, que ce soit en téléchargeant un nouveau composant ou en utilisant ce qui est fourni par Delphi, mais de préférence en utilisant ce qui est fourni par Delphi.

Auparavant, j'utilisais la commande SelectDirectory, mais je pense que les utilisateurs de mon programme auraient des difficultés à rechercher le répertoire spécifié.

Je pense que le SelectDirectory est "faible" parce que cela peut être un long processus de recherche du répertoire que vous voulez. Disons, par exemple, que vous voulez naviguer vers le répertoire Application Data. Combien de temps ou de difficultés faut-il pour y accéder ? En fin de compte, les utilisateurs peuvent même ne pas atteindre le répertoire souhaité.

J'ai besoin de quelque chose comme ça où l'utilisateur peut copier et coller des répertoires dans la barre d'adresse du répertoire en haut de la page.

enter image description here

Merci pour toutes vos réponses.

0 votes

SelectDirectory utilise le dialogue de sélection de répertoire natif du système. Vous semblez vouloir utiliser quelque chose d'autre, mais vous ne dites pas ce qui est faible dans SelectDirectory, et vous ne dites pas quelles fonctionnalités vous recherchez dans le remplacement.

0 votes

David : Ce n'est pas si simple. Le site FileCtrl.SelectDirectory a deux implémentations surchargées. L'une d'entre elles produit une boîte de dialogue de style Windows 3.1, tandis que l'autre produit une boîte de dialogue native.

0 votes

@Andreas alors la réponse est sûrement d'utiliser la bonne surcharge. Voulez-vous écrire cette réponse ? Ha, vous l'avez déjà fait !

83voto

Andreas Rejbrand Points 57164

Vous pouvez utiliser le TFileOpenDialog (sur Vista+) :

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

Personnellement, j'utilise toujours le TFileOpenDialog sur Vista+ et le repli en utilisant le SelectDirectory (le bon !) sur XP, comme ceci :

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)

0 votes

Non, je n'aime pas ce type de branchement sur la version Windows. Aussi, la fusion, cette performance solo manque de différentes manières comme demandé par OP.

3 votes

TFileOpenDialog != TOpenDialog ... TOpenDialog ne possède pas une telle option et TFileOpenDialog n'existe pas dans FireMonkey.

1 votes

Cette réponse est parfaite. Merci beaucoup !

66voto

Andreas Rejbrand Points 57164

Vous savez que les deux fonctions surchargées appelées FileCtrl.SelectDirectory produisent des dialogues totalement différents, non ?

SelectDirectory(s, [], 0);

Screenshot

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

Screenshot

3 votes

"Välf mapp" bat certainement "Select Directory" +1

0 votes

@David : Eh bien, considérez cela comme une preuve de la "nativité" du dialogue !

7 votes

Vous devriez vraiment combiner vos deux réponses en une seule et ajouter une discussion sur le changement de comportement entre Vista+ et XP.

8voto

Shadab Mozaffar Points 81

Il suffit d'inclure

FileCtrl.pas

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

Laissez le deuxième argument vide si vous voulez voir tous les répertoires, y compris le bureau. Si vous définissez le deuxième argument comme un chemin d'accès valide, votre boîte de dialogue affichera ce chemin d'accès au dossier supérieur et vous ne pourrez pas naviguer au-delà.

Par exemple :

SelectDirectory('Your caption','C:\',sDir) ne vous laissera pas sélectionner autre chose que C:\ comme D:\ ou E:\ etc.

Il est donc bon de le laisser vide.

6voto

RobertFrank Points 4374

Je viens de trouver le code ci-dessous qui semble fonctionner correctement sous XP et Vista, Win7. Il fournit une interface utilisateur permettant à un utilisateur de sélectionner un répertoire. Il utilise TOpenDialog, mais lui envoie quelques messages pour nettoyer l'apparence dans le but de sélectionner un répertoire.

Après avoir souffert des capacités limitées offertes par Windows lui-même, c'est un plaisir de pouvoir offrir à mes utilisateurs une interface utilisateur familière où ils peuvent parcourir et sélectionner une liste de produits. dossier confortablement.

Cela faisait longtemps que je cherchais quelque chose comme ça, alors j'ai pensé le poster ici pour que d'autres puissent en profiter.

Voici à quoi cela ressemble dans 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 votes

J'aime bien, mais c'est un peu ennuyeux de devoir sélectionner le dossier deux fois à la dernière étape. Et on ne peut rien sélectionner d'autre que le dernier répertoire d'une arborescence.

0 votes

Peu importe ce que vous définissez pour InitialDir, il s'ouvre sur le dossier Documents, ce qui le rend inutile.

3voto

yonojoy Points 1121

Si vous utilisez JVCL vous pouvez utiliser TJvSelectDirectory. Avec cette fonction, vous pouvez passer de l'ancien au nouveau style en définissant une propriété. Par exemple :

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;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X