0

I use FileCtrl.SelectDirectory to show a 'open folder' dialog. However, I am unhappy with it because it doesn't allow the user to enter a path from where to start the browsing. For example, if the user already has the path in clipboard it should be able to enter it into my dialog instead of wasting 12 seconds to navigate (open) lots of folders until it gets there.

I have found this code which seems to do EXACTLY what FileCtrl.SelectDirectory does. i hopped it will allow me to configure the dialog more. It doesn't.

So, how do I show a editbox in the SelectDirectory where the user can enter the path?

The solution that I have now, is my own dialog box. It is build from zero using TDirectory and TListBox. Very handy. BUT it looks so obsole because it uses Embarcadero's file management controls (TDirectory, TListBox) and we all know how dull they look like.


To make it clear: I would like something like FileCtrl.SelectDirectory but with an extact TEdit or a crumbar where the user can enter its path (if he has any). Example: enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
Gabriel
  • 20,797
  • 27
  • 159
  • 293
  • 4
    You can use the standard open file dialog in [directory selection mode](http://stackoverflow.com/questions/7422689/selecting-a-directory-with-topendialog). – Andreas Rejbrand Oct 21 '13 at 18:17
  • Hi Andreas - I could do that but it behaves bad. The 'c:' branch is somewhere below (at the bottom) of the panel. If I double click it to start the browsing process, the branches that opens, opens out of the screen or very close to the bottom, so the user has to drag the scrollbar to make all those branches visible. The WORST is that EVERY TIME I open a new sub-branch, the whole stuff is moved down (again out of screen) so the user has to scroll again. – Gabriel Oct 21 '13 at 18:56
  • davea gave the correct answer below, but unfortunately he removed it. – Andreas Rejbrand Oct 21 '13 at 19:22
  • See my answer to this here: http://stackoverflow.com/questions/7422689/selecting-a-directory-with-topendialog/18638375#18638375. It does not have the edit box though, but perhaps it'll give you a starting point? – RobertFrank Oct 21 '13 at 21:33
  • I would immediately pursue the opportunity to design my own folder picker dialog, as I've done a few different times. It's rather simple to use the Windows API to query disk drives and their folder structures. I've made use of tree views to allow users to browse directories with all my own code customized within. I have yet to turn it into a real published dialog box. – Jerry Dodge Oct 22 '13 at 03:50
  • @JerryDodge-Please let us know when it is ready. – Gabriel Oct 22 '13 at 20:43
  • @all-I added an image (scree shot from another program) to clearly show what I mean. – Gabriel Oct 22 '13 at 20:43
  • @Altar: Isn't that simply `sdShowEdit` (well, except for the position of the edit control)? Oh, I just realised you can get the edit both above and below the tree view, depending on the presence of the `sdNewUI` option. – Andreas Rejbrand Oct 22 '13 at 23:27
  • @Altar I think the scrolling behaviour you don't like in TOpenDialog is a bug in some windows versions. You may wish to experiment with Folder Options - General tab - Navigation pane settings in Windows Explorer. I remember installing a classic shell to fix the scrolling bad behaviour, but perhaps a windows upgrade or changing those Navigation pane settings will help you. – Sam Oct 22 '13 at 23:52

5 Answers5

2

If you use the overloaded version of SelectDirectory() that has a Root parameter, it calls SHBrowseForFolder() internally (the other overload displays a custom VCL Win3.1-style dialog instead). If you assign an initial value to the variable that you pass to the Directory parameter, it gets passed to SHBrowseForFolder() as the initial selected folder. You can also specify the sdShowEdit flag in the Options parameter. However, the edit box is not meant for entering full paths. But, if you call SHBrowseForFolder() directly, you can provide your own callback function for it, so when the dialog sends you a BFFM_VALIDATEFAILED event for instance, you can grab the text from the dialog's edit box and send the dialog window a BFFM_SETSELECTION message to navigate to the correct path.

What you are really asking for is the customization provided by the Vista+ IFileDialog dialog instead. You can use the IFileDialogCustomize interface to add custom controls to the dialog, such as edit boxes and buttons, and then implement the IFileDialogControlEvents interface to know when various actions occur on those controls, like button clicks. You can use that to check your custom edit box, or the clipboard, for a valid path and if detected then tell the dialog to navigate to that path via the IFileDialog.SetFolder() method.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Nooo... I don't want to PRAGMATICALLY select the start folder. I want to let the user jump to a folder (for example if he has the path in Clipboard) without browsing all the way there :) – Gabriel Oct 21 '13 at 18:28
  • 1
    Well if the user has a path in the clipboard, you can detect that before opening the dialog and open it using that path – Anya Shenanigans Oct 21 '13 at 18:29
  • 1
    But what if the user has a path on the clipboard but doesn't want to browse to that path? – Andreas Rejbrand Oct 21 '13 at 18:30
  • 1
    Prompt the user - "There is a path detected on the clipboard, would you like to start at that path?" :) – Remy Lebeau Oct 21 '13 at 18:30
  • If the user doesn't want to past a path OR has no path to past it won't. It will leave the 'Path' crumb bar as it is. – Gabriel Oct 21 '13 at 18:33
  • @davea - no. it doesn't. when you write a path and hit ENTER, the OK button will receive the ENTER. – Gabriel Oct 21 '13 at 19:57
  • @davea: And if you specify `sdValidateDir`, you will get a popup message complaining about an invalid path. Hense my suggestion to call `SHBrowseForFolder()` directly to catch that condition so you can do your own handling. – Remy Lebeau Oct 22 '13 at 01:03
  • @Altar, @Remy: What are you talking about? It works perfectly (both with and without `sdNewUI`) in Delphi 2009, Windows 7 Home Premium 64-bit. – Andreas Rejbrand Oct 22 '13 at 23:34
2

Passing sdShowEdit to FileCtrl.SelectDirectory adds an edit box that you can paste a directory into.

  FileCtrl.SelectDirectory('Caption', 'C:\', Dir, [sdNewUI, sdShowEdit]);
davea
  • 654
  • 1
  • 6
  • 14
  • 1
    This is *the* solution. (Try both with and without `sdNewUI`. Both work perfectly, as far as I can see.) – Andreas Rejbrand Oct 22 '13 at 23:30
  • 1
    I'm a little confused. I had deleted this answer as I don't believe it fully answers the question. It shows an "editbox in the SelectDirectory where the user can enter the path" but, as Altar has pointed out it does not "allow the user to enter a path from where to start the browsing". – davea Oct 23 '13 at 18:40
  • @davea: Fair point. Still, it is not clear if that is the most essential part of the question. It might be. – Andreas Rejbrand Oct 24 '13 at 10:56
  • @AndreasRejbrand-Yes, the user should be able to edit the path. – Gabriel Sep 16 '16 at 09:35
  • @AndreasRejbrand - I missed the sdShowEdit parameter. – Gabriel Sep 16 '16 at 09:58
1

TJvDirectoryEdit from Jedi VCS does that. Look it up.

Here are some pictures of it:

enter image description here

enter image description here

ioan ghip
  • 1,202
  • 2
  • 16
  • 27
  • I don't like Jedi package. I have tried it 2-3 years ago. Too big, too entangled, too unstable. – Gabriel Oct 22 '13 at 20:47
  • @Altar I never had any problems with Jedi VCS. Here is how it looks like: http://imgur.com/a/SYrys – ioan ghip Oct 23 '13 at 17:00
  • But in your screenshot I don't see the editbox that allows the user to enter the path!!!!! – Gabriel Oct 24 '13 at 01:55
  • @Altar the edit box where the folder name is, is editable. You can see in my first screen shot that I actually wrote "I'm editing this". So the user can write the path (or paste from clipboard) or... select it with the "browse for folder" dialog. – ioan ghip Oct 24 '13 at 16:46
  • It definitively does not answer MY specific question, but the solution is nice. +1 – Gabriel Sep 16 '16 at 10:07
0

If I understand correctly I think this could be your solution.

 procedure TForm1.Button1Click(Sender: TObject);
 var
  opendialog : Topendialog;
 begin
   openDialog := TOpenDialog.Create(self);
   openDialog.InitialDir := GetCurrentDir; {This can also be what is on the clipboard}
   openDialog.Options := [ofFileMustExist];
   openDialog.Filter := 'Text Document |*.txt'; {This is the type of file the user must open}
   openDialog.FilterIndex := 1;
   opendialog.execute;
end;

This code creates and shows a simple open dialog. The path the user then selected is:

opendialog.filename
Craig
  • 548
  • 9
  • 24
0

@davea's answer is ok but it only shows the old (WinXP) dialog style.

So, this is the code I use now. On Win Vista and up it shows the new style dialog and the old style on Win XP:

{$WARN SYMBOL_PLATFORM OFF}
{$IFDEF MSWindows}

function SelectAFolder(VAR Folder: string; CONST Options: TFileDialogOptions= [fdoPickFolders, fdoForceFileSystem, fdoPathMustExist, fdoDefaultNoMiniMode]): Boolean;   { Keywords: FolderDialog, BrowseForFolder}    { Works with UNC paths }
VAR Dlg: TFileOpenDialog;
begin
 { Win Vista and up }
 if OS_IsWindowsVistaUp then
  begin
   Dlg:= TFileOpenDialog.Create(NIL);   { Class for Vista and newer Windows operating systems style file open dialogs }
    TRY
      Dlg.Options       := Options;         
      Dlg.DefaultFolder := Folder;
      Dlg.FileName      := Folder;
      Result            := Dlg.Execute;
      if Result
      then Folder:= Dlg.FileName;
    FINALLY
      FreeAndNil(Dlg);
    END;
  end
 else
   { Win XP or down }
   Result:= vcl.FileCtrl.SelectDirectory('', ExtractFileDrive(Folder), Folder, [sdNewUI, sdShowEdit, sdNewFolder], nil);

 if Result
 then Folder:= Trail(Folder);
end;
{$ENDIF}
{$WARN SYMBOL_PLATFORM On}

{ Keywords: FolderDialog, BrowseForFolder}
Gabriel
  • 20,797
  • 27
  • 159
  • 293