以下代码在不同的计算机上获得不同的结果。一台机器只提供桌面文件夹(不需要),另一台提供桌面文件夹和计算机,映射驱动器(所需)。
procedure TForm1.Button1Click(Sender: TObject);
var
Directory : String;
begin
FileCtrl.SelectDirectory('Caption', 'Desktop', Directory, [sdNewUI, sdShowEdit]);
end;
它给出的一台机器:
在另一个上它给出了:
这感觉就像一个窗户设置,但我不知道从哪里开始。使用Delphi XE,Windows 10。
任何想法都表示赞赏。谢谢你的时间。
答案 0 :(得分:3)
解决方法强>
使用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);
...
以下是IDesktopFolder.ParseDisplayName的MSDN所说的内容:
pszDisplayName [in]
类型:LPWSTR
带有显示名称的以null结尾的Unicode字符串。因为每个Shell文件夹定义了自己的解析语法,所以此字符串可以采用的形式可能会有所不同。例如,桌面文件夹接受诸如“C:\ My Docs \ My File.txt”之类的路径。它还将使用“:: {GUID}”语法接受对名称空间中具有与其关联的GUID的项的引用。
请注意,该文档指出桌面文件夹将接受路径和GUID。它不接受'Desktop'
。因为那都不是。
'Desktop'
作为root
在一个系统上运行但不在另一个系统上运行的事实是在IDesktopFolder
接口的较旧/较新版本中进行的一些未记录的修复。
技术解决方案
使用''
作为“root”,如上面的代码所示。
显然SelectDirectory
是微软的一个非常糟糕的设计,永远不应该被使用。它只是在很多方面很糟糕。我建议尽可能不使用它。