Selecting a directory with TOpenDialog

橙三吉。 提交于 2019-11-27 18:06:54

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) 

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

SelectDirectory(s, [], 0); 

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

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:

//*********************** //** 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; 
Shadab Mozaffar

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.

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;  
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!