Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

way to specify start directory with BrowseDialogCallBack 1

Status
Not open for further replies.

CADTenchy

Technical User
Dec 12, 2007
237
GB

Is there a way I can specify a fixed starting directory for the broswe dialog to use, in the code below?

Code:
uses ShellAPI, ShlObj;

...

function BrowseDialogCallBack
  (Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): 
  integer stdcall;
var
  wa, rect : TRect;
  dialogPT : TPoint;
begin
  //center in work area
  if uMsg = BFFM_INITIALIZED then
  begin
    wa := Screen.WorkAreaRect;
    GetWindowRect(Wnd, Rect);
    dialogPT.X := ((wa.Right-wa.Left) div 2) - 
                  ((rect.Right-rect.Left) div 2);
    dialogPT.Y := ((wa.Bottom-wa.Top) div 2) - 
                  ((rect.Bottom-rect.Top) div 2);
    MoveWindow(Wnd,
               dialogPT.X,
               dialogPT.Y,
               Rect.Right - Rect.Left,
               Rect.Bottom - Rect.Top,
               True);
  end;

  Result := 0;
end;
Code:
function BrowseDialog
 (const Title: string; const Flag: integer): string;
var
  lpItemID : PItemIDList;
  BrowseInfo : TBrowseInfo;
  DisplayName : array[0..MAX_PATH] of char;
  TempPath : array[0..MAX_PATH] of char;
begin
  Result:='';
  FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);
  with BrowseInfo do begin
    hwndOwner := Application.Handle;
    pszDisplayName := @DisplayName;
    lpszTitle := PChar(Title);
    ulFlags := Flag;
    lpfn := BrowseDialogCallBack;
  end;
  lpItemID := SHBrowseForFolder(BrowseInfo);
  if lpItemId <> nil then begin
    SHGetPathFromIDList(lpItemID, TempPath);
    Result := TempPath;
    GlobalFreePtr(lpItemID);
  end;
end;
Code:
procedure TForm1.Button1Click(Sender: TObject);
var
  sFolder : string;
begin
  sFolder := BrowseDialog('Select a folder', 
                          BIF_RETURNONLYFSDIRS);

  if sFolder <> '' then
    ShowMessage('Selected: ' + #13#10 + sFolder);
end;


Steve (Delphi 2007 & XP)
 
Okay...

In your callback function, add this below your movewindow() function:

Code:
{ set browse directory }
SendMessage(wnd, BFFM_SETSELECTIONA, Longint(true), lpdata);

and lpdata is set in the BrowseInfo record. (it's wierd like this, we're really passing a PChar, but the parm is defined as longint in TBrowseInfo)

Code:
{ set initial directory }
BrowseInfo.lParam := Longint(PChar(Start_Dir));

where start_dir is a string passed in the procedure parm of BrowseDialog.
 
Hi Glenn,

Thanks for feedback. I don't think I could have ever worked that out, esp the passing a Pchar to a longint!

Can I just check I've understood you correctly (currently at a Delphi free station so can't test).

This section I'm OK with (hopefully!):
Code:
uses ShellAPI, ShlObj;

...

function BrowseDialogCallBack
  (Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM):
  integer stdcall;
var
  wa, rect : TRect;
  dialogPT : TPoint;
begin
  //center in work area
  if uMsg = BFFM_INITIALIZED then
  begin
    wa := Screen.WorkAreaRect;
    GetWindowRect(Wnd, Rect);
    dialogPT.X := ((wa.Right-wa.Left) div 2) -
                  ((rect.Right-rect.Left) div 2);
    dialogPT.Y := ((wa.Bottom-wa.Top) div 2) -
                  ((rect.Bottom-rect.Top) div 2);
    MoveWindow(Wnd,
               dialogPT.X,
               dialogPT.Y,
               Rect.Right - Rect.Left,
               Rect.Bottom - Rect.Top,
               True);
  [highlight]
    SendMessage(wnd, BFFM_SETSELECTIONA, Longint(true), lpdata);
[/highlight]
  end;

  Result := 0;
end;

I'm less clear with placing the other line, and implementing it.

Can/do I do this(I want start directory to be coded in)?
Code:
function BrowseDialog
 (const Title: string; const Flag: integer): string;
var
  lpItemID : PItemIDList;
  BrowseInfo : TBrowseInfo;
  DisplayName : array[0..MAX_PATH] of char;
  TempPath : array[0..MAX_PATH] of char;
begin
  Result:='';
  FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);
  with BrowseInfo do begin
    hwndOwner := Application.Handle;
    pszDisplayName := @DisplayName;
    lpszTitle := PChar(Title);
    ulFlags := Flag;
[highlight]
    lParam := Longint(PChar('F:\PCB\Altium\Projects'));
[/highlight]
    lpfn := BrowseDialogCallBack;
  end;
  lpItemID := SHBrowseForFolder(BrowseInfo);
  if lpItemId <> nil then begin
    SHGetPathFromIDList(lpItemID, TempPath);
    Result := TempPath;
    GlobalFreePtr(lpItemID);
  end;
end;

Steve (Delphi 2007 & XP)
 
Looks like what you have should work right. The only possible problem I see (assuming Delphi isn't going to want a variable instead of a constant for the lparam line) is if you're working with Unicode you'll want BFFM_SETSELECTIONW instead of BFFM_SETSELECTIONA.

Hope it works right!
 
Hi Glenn,

Finally got to test this, and works a treat. Thanks!


Steve (Delphi 2007 & XP)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top