Question

I am trying to create an open dialog (in Windows 7) where the user is confined to the initial directory. On the open dialog I have set the optionsEX to [ofExNoPlacesBar] and that removes the bar that would let them select folders and directories to go to quickly but the user can use the bread crumb address tool to go up a level and type a different directory into the filename text box to change directories.

Thank you

Was it helpful?

Solution

If you are using Delphi 2009+, there is a TFileOpenDialog. Use this, and set

procedure TForm3.FileOpenDialog1FolderChange(Sender: TObject);
begin
  FInitiated := true;
end;

procedure TForm3.FileOpenDialog1FolderChanging(Sender: TObject;
  var CanChange: Boolean);
begin
  CanChange := not FInitiated;
end;

procedure TForm3.btnOpenClick(Sender: TObject);
begin
  FInitiated := false;
  FileOpenDialog1.DefaultFolder := 'C:\MyFolder\';
  FileOpenDialog1.Execute;
end;

where

var
  FInitiated: boolean;

(Notice that there should be exactly one FInitiated per TFileOpenDialog. So, if FileOpenDialog is a private member of TForm3, let FInitiated be a private member of TForm3 as well.)

To improve the user experience, you will probably use

procedure TForm3.FileOpenDialog1FolderChanging(Sender: TObject;
  var CanChange: Boolean);
begin
  CanChange := not FInitiated;
  if not CanChange then beep;
end;

or

procedure TForm3.FileOpenDialog1FolderChanging(Sender: TObject;
  var CanChange: Boolean);
begin
  CanChange := not FInitiated;
  if not CanChange then
    MessageBox(Handle, PChar('Directory selection is not allowed.'), PChar(Caption), MB_ICONINFORMATION);
end;

OTHER TIPS

Use a different open dialog (make a form yourself with no folder navigation, only a file list box), or simply audit for a path not matching the initial dir and refuse to actually open the file.

The 'FileOpenDialog' has an OnFolderChanging event of type TFileDialogFolderChangingEvent which have a boolean CanChange parameter. I'd expect setting this parameter to false would serve the purpose.

edit:
Example usage as per Remy's comments (if I understood correctly);

procedure TForm1.FileOpenDialog1FolderChanging(Sender: TObject;
  var CanChange: Boolean);
var
  Dlg: TFileOpenDialog;
  DefFolder: IShellItem;
  iOrder: Integer;
begin
  CanChange := False;
  Dlg := Sender as TFileOpenDialog;
  if Succeeded(SHCreateItemFromParsingName(PWideChar(WideString(Dlg.DefaultFolder)), nil, IShellItem, DefFolder)) then
  try
    CanChange := Dlg.ShellItem.Compare(DefFolder, SICHINT_ALLFIELDS, iOrder) = S_OK;
  finally
    DefFolder := nil;
  end;
end;

The below also works but more vulnerable to path variations (see Andreas' comments below);

procedure TForm1.FileOpenDialog1FolderChanging(Sender: TObject;
  var CanChange: Boolean);
begin
  CanChange := SameFileName(TFileOpenDialog(Sender).FileName,
                            TFileOpenDialog(Sender).DefaultFolder);
end;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top