多次设置“选择目录对话框”的“InitialDir”属性

Setting `InitialDir` property of `TSelectDirectoryDialog` mutiple times

我正在尝试使用 TSelectDirectoryDialogInitialDir 属性:

procedure selectfolder;
begin
SelectDirectoryDialog1.InitialDir := strPath;
If SelectDirectoryDialog1.Execute then begin
   Edit1.Text := SelectDirectoryDialog1.FileName; 
   end;
end;

第一次(strPath=X)它工作正常,第二次我使用这个过程(strPath=Y)它没有使用新路径(Y),而是我选择的那个以前。

在我第二次设置 InitialDir 属性 之前,是否必须调用方法,例如 SelectDirectoryDialog1."reinitiate"?另一个想法是使用与 InitialDir 不同的 属性,但我不知道哪个可以完成这项工作。不幸的是,TSelectDirectoryDialogdoc page 目前已关闭,因此我没有关于 TSelectDirectoryDialog 的可用 methods/properties 以及我测试过的解决问题的说明。

如果我手动创建 TSelectDirectoryDialog class 实例并且不使用 Component Palette 中的实例来创建它 "on the form",我就可以使用它。然后我就销毁实例并创建一个新实例。

procedure TForm1.Button4Click(Sender: TObject);
var SelectDirectoryDialogManual : TSelectDirectoryDialog;
begin

SelectDirectoryDialogManual := TSelectDirectoryDialog.Create(nil);
SelectDirectoryDialogManual.InitialDir := 'C:\Windows';
if SelectDirectoryDialogManual.Execute then ShowMessage(SelectDirectoryDialogManual.FileName);
SelectDirectoryDialogManual.Free;
end; 

但是,当我使用组件组件面板创建 SelectDirectoryDialog1 时,我该怎么做呢?

通过在每次调用 Execute 之前保存和恢复 InitialDir 的值,或者按照@Sertac 在评论中所说的进行操作,但效果不佳 "self-documenting" imo,ymmv。

下面的代码对我来说工作正常。 edInitialDir 是一个 TEdit,它保存最近使用 SelectDirectoryDialog1 选择的目录,然后用于下一次调用。

procedure TForm1.Button1Click(Sender: TObject);
begin
  SelectDirectoryDialog1.InitialDir := edInitialDir.Text;

  if SelectDirectoryDialog1.Execute then
    Caption := 'executed'
  else
    Caption := 'not executed';

  edInitialDir.Text := SelectDirectoryDialog1.FileName;
end;

注意:SelectDirectoryDialog1 的所有属性都是从 Component Palette 新添加的实例的默认值。

关于您的评论,TSelectDirectoryDialog.Execute 调用 TWin32WSSelectDirectoryDialog.CreateHandle(参见 Dialogs.Pas,第 1219 行)。开头部分如下:

class function TWin32WSSelectDirectoryDialog.CreateHandle(const ACommonDialog: TCommonDialog): THandle;
var
  Options : TOpenOptions;
  InitialDir : string;
  Buffer : PChar;
  bi : TBrowseInfo;
  iidl : PItemIDList;
  biw : TBROWSEINFOW;
  Bufferw : PWideChar absolute Buffer;
  InitialDirW: widestring;
  Title: widestring;
  DirName: string;
begin
  DirName := '';
  InitialDir := TSelectDirectoryDialog(ACommonDialog).FileName;
  Options := TSelectDirectoryDialog(ACommonDialog).Options;

  if length(InitialDir)=0 then
    InitialDir := TSelectDirectoryDialog(ACommonDialog).InitialDir;
  if length(InitialDir)>0 then begin
    // remove the \ at the end.                                                                      
    if Copy(InitialDir,length(InitialDir),1)=PathDelim then
      InitialDir := copy(InitialDir,1, length(InitialDir)-1);
    // if it is a rootdirectory, then the InitialDir must have a \ at the end.
    if Copy(InitialDir,length(InitialDir),1)=DriveDelim then
      InitialDir := InitialDir + PathDelim;
  end;

从这里您可以看到它最初尝试从 FileName 属性 中导出 InitialDir 的值,只有当结果为空字符串时,它才会尝试使用 InitialDir 的存储值 属性。这就是对话框在下次调用 Execute 时使用先前选择的目录的原因,这正是您应该期望的,即使您不喜欢它。从第二次和后续调用中重新使用 IntialDir 的初始值的唯一方法是在每次调用之前恢复它。