Selecting a directory with TOpenDialog

后端 未结 5 1029
长情又很酷
长情又很酷 2020-12-04 17:40

I\'d really like to know the various ways I could select a directory with the TOpenDialog, whether it be downloading a new component or using what is provided by Delphi, but

相关标签:
5条回答
  • 2020-12-04 18:00

    Just found the code below that seems to work fine in XP and Vista, Win7. It provides a UI for a user to select a directory. It uses TOpenDialog, but sends it a few messages to clean up the appearance for the purposes of selecting a directory.

    After suffering from the limited capabilities provided by Windows itself, it's a pleasure to be able to give my users a familiar UI where they can browse and select a folder comfortably.

    I'd been looking for something like this for a long time so thought I'd post it here so others can benefit from it.

    Here's what it looks like in 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;
    
    0 讨论(0)
  • 2020-12-04 18:01

    You do know that the two overloaded functions called FileCtrl.SelectDirectory produces entirely different dialogs, right?

    SelectDirectory(s, [], 0);
    

    Screenshot

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

    Screenshot

    0 讨论(0)
  • 2020-12-04 18:01

    If you are using JVCL you can use TJvSelectDirectory. With this you can switch between old and new style by setting a property. For example:

    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; 
    
    0 讨论(0)
  • 2020-12-04 18:14

    Just include

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

    Just leave second argument empty if want to see all directories including desktop. If you set second argument to any valid Path, then your dialog will have that path to top folder and you can not navigate beyond that.

    For example:

    SelectDirectory('Your caption','C:\',sDir) will not let you select anything beyond C:\, like D:\ or E:\ etc.

    So it is good to leave it empty.

    0 讨论(0)
  • 2020-12-04 18:20

    You can use the TFileOpenDialog (on Vista+):

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

    Personally, I always use the TFileOpenDialog on Vista+ and fallback using the SelectDirectory (the good one!) on XP, like this:

    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 讨论(0)
提交回复
热议问题