解决方法
改为使用TFileOpenDialog
*。
设置FileOpenDialog1.Options:= [fdoPickFolders,fdoPathMustExist]
现在你有一个对话框:
*)不与TOpenDialog,不允许您只选择文件夹混淆。
为Windows XP
注意解决方案,新的TFileOpenDialog仅适用于Vista和上面。
如果包含此控件,则您的程序将无法在XP上运行。
如果您在XP上启动对话框,它将生成一个EPlatformVersionException
。
您可能需要使用下面的代码代替,如果你想成为向后兼容:
uses JclSysInfo; //because you have XE use JCL.
...
var
WinMajorVer: Integer;
Directory: string;
FileDialog: TFileOpenDialog;
begin
WinMajorVer:= GetWindowsMajorVersionNumber;
if WinMajorVer < 6 then begin //pre-vista
//To show the root Desktop namespace, you should be setting the Root parameter to an empty string ('') instead of 'Desktop'
FileCtrl.SelectDirectory('Caption', '', Directory, [sdNewUI, sdShowEdit]);
end else begin
FileDialog:= TFileOpenDialog.Create(self);
try
FileDialog.Options:= [fdoPickFolders,fdoPathMustExist];
if FileDialog.Execute then Directory:= FileOpenDialog1.FileName;
finally
FileDialog.Free;
end;
end;
Result:= Directory;
end;
推荐阅读:
detect windows version
编辑
FileCtrl.SelectDirectory('Caption', 'Desktop', Directory, [sdNewUI, sdShowEdit]);
的'Desktop'
进入Root
参数,它是像这样处理的:
...
SHGetDesktopFolder(IDesktopFolder);
IDesktopFolder.ParseDisplayName(Application.Handle, nil,
Root, Eaten, RootItemIDList, Flags);
...
下面是MSDN对IDesktopFolder.ParseDisplayName有说:
pszDisplayName [中]
类型:LPWSTR
以空结尾的Unicode字符串与显示名称。由于每个Shell文件夹都定义了自己的解析语法,因此该字符串可以采用的形式可能会有所不同例如,桌面文件夹接受诸如“C:\ My Docs \ My File.txt”之类的路径。它还将使用“:: {GUID}”语法接受对名称空间中具有与它们关联的GUID的项目的引用。
请注意,文档指出桌面文件夹将接受路径和GUID。它不接受'Desktop'
。因为那既不是。
'Desktop'
作为root
作用于一个系统而不是另一个系统的事实是在IDesktopFolder
接口的较旧/较新版本中进行的一些未公开的修复。
技术方案
使用''
如所示在我的代码上方的“根”。
显然SelectDirectory
是微软公司的一个非常糟糕的设计,绝对不应该使用。它只是吸引了很多方面。我建议尽可能不要使用它。
如果是我,我会使用Vista中引入的新的通用文件项目对话框,这是本机文件夹选取器 –
要显示根目录名称空间,您应该将'Root'参数设置为空字符串(''' '')而不是''Desktop''。 –
谢谢@RemyLebeau!使用''''而不是''Desktop''解决了我的问题。 – user1627960