SelectDirectory control

How can I control API SelectDirectory Browser?

I need to put it in Pos(X,Y) and set current selected directory in browser tree.
LVL 3
lmikleAsked:
Who is Participating?
 
LischkeConnect With a Mentor Commented:
Here is a solution for the initial folder problem.

function BrowseCallbackProc(hwnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer; stdcall;

// callback function used in SelectDirectory to set the status text and choose an initial dir

var Path: array[0..MAX_PATH] of Char;

begin
  case uMsg of
    BFFM_INITIALIZED:
      begin
        // Initialization has been done, now set our initial directory which is passed in lpData
        // (and set btw. the status text too).
        // Note: There's no need to cast lpData to a PChar since the following call needs a
        //       LPARAM parameter anyway.
        SendMessage(hwnd, BFFM_SETSELECTION, 1, lpData);
        SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, lpData);
      end;
    BFFM_SELCHANGED:
      begin
        // Set the status window to the currently selected path.
        if SHGetPathFromIDList(Pointer(lParam), Path) then SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, Integer(@Path));
      end;
  end;
  Result := 0;
end;

//-----------------------------------------------------------------------------

function SelectDirectory(const Caption, InitialDir: String; const Root: WideString;
                         ShowStatus: Boolean; out Directory: String): Boolean;

// Another (overloaded) browse-for-folder function with the ability to select an intial directory
// (other SelectDirectory functions are in FileCtrl.pas).
// I had to make this overloading unambiguous in its parameter list so I included a flag which
// indicates whether or not to show a status text line in the dialog (which will receive the
// currently selected path if enabled).

var BrowseInfo: TBrowseInfo;
    Buffer: PChar;
    RootItemIDList,
    ItemIDList: PItemIDList;
    ShellMalloc: IMalloc;
    IDesktopFolder: IShellFolder;
    Eaten, Flags: LongWord;
    Windows: Pointer;
    Path: String;

begin
  Result := False;
  Directory := '';
  Path := InitialDir;
  if (Length(Path) > 0) and (Path[Length(Path)] = '\') then Delete(Path, Length(Path), 1);
  FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
  if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
  begin
    Buffer := ShellMalloc.Alloc(MAX_PATH);
    try
      SHGetDesktopFolder(IDesktopFolder);
      IDesktopFolder.ParseDisplayName(Application.Handle, nil, PWideChar(Root), Eaten, RootItemIDList, Flags);
      with BrowseInfo do
      begin
        hwndOwner := Application.Handle;
        pidlRoot := RootItemIDList;
        pszDisplayName := Buffer;
        lpszTitle := PChar(Caption);
        ulFlags := BIF_RETURNONLYFSDIRS;
        if ShowStatus then ulFlags := ulFlags or BIF_STATUSTEXT;
        lParam := Integer(PChar(Path));
        lpfn := BrowseCallbackProc;
      end;

      // make the browser dialog modal
      Windows := DisableTaskWindows(Application.Handle);
      try
        ItemIDList := ShBrowseForFolder(BrowseInfo);
      finally
        EnableTaskWindows(Windows);
      end;

      Result :=  ItemIDList <> nil;
      if Result then
      begin
        ShGetPathFromIDList(ItemIDList, Buffer);
        ShellMalloc.Free(ItemIDList);
        Directory := Buffer;
      end;
    finally
      ShellMalloc.Free(Buffer);
    end;
  end;
end;


For positioning the window try a SetWindowPos with the given window handle (in the BFFM_INITIALIZED branch).

Ciao, Mike
0
 
PeterLarsenCommented:
var
D : TopenDialog;
begin
D:=Topendialog.create(self);
//Do what you want.
D.Execute;

Regards
Peter
0
 
PeterLarsenCommented:
This method goes for other kind of dialogs too ...
0
[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

 
LischkeCommented:
Peter, please post comments first. In particular if you cannot be sure your contribution is what the questioneer wants (and you solution is wrong in this case).

Thank you and

Ciao, Mike
0
 
PeterLarsenCommented:
Well Mike, Nice code you have there :-)
I agree, but i dont see why it's wrong - it's just a different way to do it.

Regards
Peter
0
 
LischkeCommented:
:-)) No, there's a huge difference! You open the file open dialog (a listview) while I'm using the folder open dialog (a treeview) which is for example used in install programs.

Nice trial anyway ;-)

Ciao, Mike
0
 
PeterLarsenCommented:
Well, he is free to reject the answer.
0
 
rwilson032697Commented:
Or you could use TBrowseFolder, downloadable from DSP (http://sunsite.icm.edu.pl/delphi)

This wraps SHBrwoseForFolder and allows you to easily set the initial directory...

We use it in our products...

Cheers,

Raymond.
0
 
lmikleAuthor Commented:
Sorry, but I need to control Windows API SelectDirectory. In FileCtrl this function is discribed as
 function SelectDirectory ( const Caption : String; const Root : WideString; out Dir : String) : Boolean;

It Havn't any InitialDir parameter or another.

In program it uses as

var
 LastDir; // contain a last visited directory

....
....

var
 Fldr : String;

....

If SelectDirectory('Open folder','Desktop',Fldr) Then
 Begin
  ...
  LastDir := Fldr;
 End;

....

But i find in any programs (Microsoft's Find for example) that this dialog can be positioned in any place and initial folder was selected in tree.

May be initial dir can be selected by passing special format Root parameter? or by any CallBack function without overloading SelectDirectory.

0
 
LischkeCommented:
Am I invisible or what? lmikle, would you please look at the code I posted above? It contains exactly what you need!

Ciao, Mike
0
 
intheCommented:
Imikle,

mike(Lischke) has posted what you want ,the  SelectDirectory with a callback proc .
there is a example comp for this i think at delphifreestuff but it does the same as mike posted .
mike you should post as answer it works fine..
0
 
LischkeCommented:
Thank you Barry for standing by and lmikle for the points. I hope it is really want you need, lmikle. Otherwise just ask...

Ciao, Mike
0
All Courses

From novice to tech pro — start learning today.