设置“ TSelectDirectoryDialog”多次的“ InitialDir”属性

时间:2018-09-04 15:44:00

标签: lazarus freepascal

我正在尝试使用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不同的属性,但我不知道哪个可以完成这项工作。不幸的是,TSelectDirectoryDialog的{​​{3}}目前处于关闭状态,因此我没有描述TSelectDirectoryDialog的可用方法/属性以及为解决问题而测试的方法/属性。

如果我手动创建TSelectDirectoryDialog类实例,并且不使用“组件面板”中的一个实例在“表单上”创建它,我就可以使用它。然后,我只是销毁实例并创建一个新实例。

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; 

但是当我使用组件Component Palette创建SelectDirectoryDialog1时该怎么做?

1 个答案:

答案 0 :(得分:3)

通过在每次调用Execute之前保存并恢复InitialDir的值,或执行@Sertac在注释中所说的那样,该方法虽然有效,但不太“自我记录” imo ymmv。

下面的代码对我来说很好。 edInitialDirTEdit,它保存使用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的所有属性是从组件面板中新添加的实例的默认值。

关于您的注释,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初始值的唯一方法是在每次调用之前将其还原。