Delphi 使用Firemonkey框架选择一个文件夹

Delphi 使用Firemonkey框架选择一个文件夹,delphi,Delphi,我想使用DelphiXe2将以下短代码片段从VCL移植到FM with TFileOpenDialog.Create(nil) do try Title := 'Select Directory'; Options := [fdoPickFolders, fdoPathMustExist, fdoForceFileSystem]; OkButtonLabel := 'Select'; DefaultFolder := FDir; FileName

我想使用DelphiXe2将以下短代码片段从VCL移植到FM

 with TFileOpenDialog.Create(nil) do
   try
    Title := 'Select Directory';
    Options := [fdoPickFolders, fdoPathMustExist, fdoForceFileSystem];
    OkButtonLabel := 'Select';
    DefaultFolder := FDir;
    FileName := FDir;
    if Execute then
       ShowMessage(FileName);
   finally
    Free;
 end
我找不到使用FM框架导入相关单元的帮助。至少filecrtl单元似乎不再可用
此外,解决方案在我的测试应用程序中也没有出现窗口。

因为您使用的是Windows,所以即使在FireMonkey应用程序中,您也可以使用问题中的代码。我认为您需要将代码放入一个不使用任何FMX单元的单元中,否则它可以正常工作。您需要在该单元中使用Vcl.对话框。

因为您使用的是Windows,所以即使在FireMonkey应用程序中,您也可以使用问题中的代码。我认为您需要将代码放入一个不使用任何FMX单元的单元中,否则它可以正常工作。您需要在该单元中使用Vcl.Dialogs。

这对于XE4中的新FireMonkey HD应用程序(在Win32 64上运行,同时作为Win32和Win32 64目标)很好

当然,这是特定于Windows的。您可以使用操作系统版本说明(
WinVistaSelectFolder
WinXPSelectFolder
),或者只需调用通用的
SelectFolder
,即可完成此操作

unit WinFolderSelectUtils;

interface

uses
  SysUtils;

function SelectFolder: string;    
function WinVistaSelectFolder: string;
function WinXPSelectFolder: string;

implementation

uses
  ShellAPI, ShlObj, ActiveX, Windows;

function SelectFolder: string;
begin
  if TOSVersion.Check(6) then
    Result := WinVistaSelectFolder
  else
    Result := WinXPSelectFolder;
end;

function WinXPSelectFolder: string;
var
  BrowseInfo: TBrowseInfo;
  ItemIDList: PItemIDList;
  ItemSelected: PItemIDList;
  NameBuffer: array[0..MAX_PATH] of Char;
begin
  Result := '';

  // Should be doing some error handling here. Omitted for clarity, but
  // obviously should raise some sort of exception if anything fails instead
  // of just returning an empty string.
  ItemIDList := nil;
  FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
  BrowseInfo.hwndOwner := 0;
  BrowseInfo.pidlRoot := ItemIDList;
  BrowseInfo.pszDisplayName := NameBuffer;
  BrowseInfo.lpszTitle := 'Select a directory';
  BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;
  ItemSelected := SHBrowseForFolder(BrowseInfo);
  if ItemSelected <> nil then
  begin
    SHGetPathFromIDList(ItemSelected, NameBuffer);
    Result := NameBuffer;
  end;
  CoTaskMemFree(BrowseInfo.pidlRoot);
end;

function WinVistaSelectFolder: String;
var
  FileDialog: IFileDialog;
  hr: HRESULT;
  IResult: IShellItem;
  FileName: PWideChar;
  Settings: Cardinal;
  Title: String;
begin
  hr := CoCreateInstance(CLSID_FileOpenDialog,
                         nil,
                         CLSCTX_INPROC_SERVER,
                         IFileDialog,
                         FileDialog);
  if hr = S_OK then
  begin
    FileDialog.GetOptions(Settings);
    Settings := Settings or FOS_PICKFOLDERS or FOS_FORCEFILESYSTEM;
    FileDialog.SetOptions(Settings);
    FileDialog.SetOkButtonLabel('Select');
    Title := 'Select a directory';
    FileDialog.SetTitle(PWideChar(Title));
    hr := FileDialog.Show(0);
    if hr = S_OK then
    begin
      hr := FileDialog.GetResult(IResult);
      if hr = S_OK then
      begin
        IResult.GetDisplayName(SIGDN_FILESYSPATH, FileName);
        Result := FileName;
      end;
    end;
  end;
end;
单位WinFolderSelectUtils;
接口
使用
SysUtils;
函数SelectFolder:string;
函数WinVistaSelectFolder:字符串;
函数WinXPSelectFolder:string;
实施
使用
ShellAPI、ShlObj、ActiveX、Windows;
函数SelectFolder:string;
开始
如果要更改版本,请选中(6),然后
结果:=WinVistaSelectFolder
其他的
结果:=WinXPSelectFolder;
结束;
函数WinXPSelectFolder:string;
变量
BrowseInfo:TBrowseInfo;
ItemIDList:PItemIDList;
所选项目:PItemIDList;
NameBuffer:Char的数组[0..MAX_PATH];
开始
结果:='';
//应该在这里做一些错误处理。为清楚起见省略,但
//显然,如果有什么东西失败了,我们应该提出某种例外
//只是返回一个空字符串。
ItemIDList:=nil;
FillChar(BrowseInfo,SizeOf(BrowseInfo),0;
BrowseInfo.hwndOwner:=0;
BrowseInfo.pidlRoot:=ItemIDList;
BrowseInfo.pszDisplayName:=NameBuffer;
BrowseInfo.lpszTitle:=“选择一个目录”;
BrowseInfo.ulFlags:=BIF_RETURNONLYFSDIRS;
所选项目:=SHBrowseForFolder(BrowseInfo);
如果选择“无”,则
开始
SHGetPathFromIDList(ItemSelected,NameBuffer);
结果:=NameBuffer;
结束;
CoTaskMemFree(BrowseInfo.pidlRoot);
结束;
函数WinVistaSelectFolder:字符串;
变量
文件对话框:IFileDialog;
hr:HRESULT;
结果:IShellItem;
文件名:PWideChar;
设置:基数;
标题:字符串;
开始
hr:=CoCreateInstance(CLSID_文件打开对话框,
无
CLSCTX_INPROC_服务器,
如果对话,
文件对话框);
如果hr=S_正常,则
开始
FileDialog.GetOptions(设置);
设置:=设置或FOS_PICKFOLDERS或FOS_Force文件系统;
FileDialog.SetOptions(设置);
FileDialog.SetOkButtonLabel('Select');
标题:='选择目录';
SetTitle(PWideChar(Title));
hr:=FileDialog.Show(0);
如果hr=S_正常,则
开始
hr:=FileDialog.GetResult(IResult);
如果hr=S_正常,则
开始
IResult.GetDisplayName(SIGDN_FILESYSPATH,FileName);
结果:=文件名;
结束;
结束;
结束;
结束;

结束。

对于XE4中的新FireMonkey HD应用程序(在Win32 64上运行,同时作为Win32和Win32 64目标)来说,这很好

当然,这是特定于Windows的。您可以使用操作系统版本说明(
WinVistaSelectFolder
WinXPSelectFolder
),或者只需调用通用的
SelectFolder
,即可完成此操作

unit WinFolderSelectUtils;

interface

uses
  SysUtils;

function SelectFolder: string;    
function WinVistaSelectFolder: string;
function WinXPSelectFolder: string;

implementation

uses
  ShellAPI, ShlObj, ActiveX, Windows;

function SelectFolder: string;
begin
  if TOSVersion.Check(6) then
    Result := WinVistaSelectFolder
  else
    Result := WinXPSelectFolder;
end;

function WinXPSelectFolder: string;
var
  BrowseInfo: TBrowseInfo;
  ItemIDList: PItemIDList;
  ItemSelected: PItemIDList;
  NameBuffer: array[0..MAX_PATH] of Char;
begin
  Result := '';

  // Should be doing some error handling here. Omitted for clarity, but
  // obviously should raise some sort of exception if anything fails instead
  // of just returning an empty string.
  ItemIDList := nil;
  FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
  BrowseInfo.hwndOwner := 0;
  BrowseInfo.pidlRoot := ItemIDList;
  BrowseInfo.pszDisplayName := NameBuffer;
  BrowseInfo.lpszTitle := 'Select a directory';
  BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;
  ItemSelected := SHBrowseForFolder(BrowseInfo);
  if ItemSelected <> nil then
  begin
    SHGetPathFromIDList(ItemSelected, NameBuffer);
    Result := NameBuffer;
  end;
  CoTaskMemFree(BrowseInfo.pidlRoot);
end;

function WinVistaSelectFolder: String;
var
  FileDialog: IFileDialog;
  hr: HRESULT;
  IResult: IShellItem;
  FileName: PWideChar;
  Settings: Cardinal;
  Title: String;
begin
  hr := CoCreateInstance(CLSID_FileOpenDialog,
                         nil,
                         CLSCTX_INPROC_SERVER,
                         IFileDialog,
                         FileDialog);
  if hr = S_OK then
  begin
    FileDialog.GetOptions(Settings);
    Settings := Settings or FOS_PICKFOLDERS or FOS_FORCEFILESYSTEM;
    FileDialog.SetOptions(Settings);
    FileDialog.SetOkButtonLabel('Select');
    Title := 'Select a directory';
    FileDialog.SetTitle(PWideChar(Title));
    hr := FileDialog.Show(0);
    if hr = S_OK then
    begin
      hr := FileDialog.GetResult(IResult);
      if hr = S_OK then
      begin
        IResult.GetDisplayName(SIGDN_FILESYSPATH, FileName);
        Result := FileName;
      end;
    end;
  end;
end;
单位WinFolderSelectUtils;
接口
使用
SysUtils;
函数SelectFolder:string;
函数WinVistaSelectFolder:字符串;
函数WinXPSelectFolder:string;
实施
使用
ShellAPI、ShlObj、ActiveX、Windows;
函数SelectFolder:string;
开始
如果要更改版本,请选中(6),然后
结果:=WinVistaSelectFolder
其他的
结果:=WinXPSelectFolder;
结束;
函数WinXPSelectFolder:string;
变量
BrowseInfo:TBrowseInfo;
ItemIDList:PItemIDList;
所选项目:PItemIDList;
NameBuffer:Char的数组[0..MAX_PATH];
开始
结果:='';
//应该在这里做一些错误处理。为清楚起见省略,但
//显然,如果有什么东西失败了,我们应该提出某种例外
//只是返回一个空字符串。
ItemIDList:=nil;
FillChar(BrowseInfo,SizeOf(BrowseInfo),0;
BrowseInfo.hwndOwner:=0;
BrowseInfo.pidlRoot:=ItemIDList;
BrowseInfo.pszDisplayName:=NameBuffer;
BrowseInfo.lpszTitle:=“选择一个目录”;
BrowseInfo.ulFlags:=BIF_RETURNONLYFSDIRS;
所选项目:=SHBrowseForFolder(BrowseInfo);
如果选择“无”,则
开始
SHGetPathFromIDList(ItemSelected,NameBuffer);
结果:=NameBuffer;
结束;
CoTaskMemFree(BrowseInfo.pidlRoot);
结束;
函数WinVistaSelectFolder:字符串;
变量
文件对话框:IFileDialog;
hr:HRESULT;
结果:IShellItem;
文件名:PWideChar;
设置:基数;
标题:字符串;
开始
hr:=CoCreateInstance(CLSID_文件打开对话框,
无
CLSCTX_INPROC_服务器,
如果对话,
文件对话框);
如果hr=S_正常,则
开始
FileDialog.GetOptions(设置);
设置:=设置或FOS_PICKFOLDERS或FOS_Force文件系统;
FileDialog.SetOptions(设置);
FileDialog.SetOkButtonLabel('Select');
标题:='选择目录';
SetTitle(PWideChar(Title));
hr:=FileDialog.Show(0);
如果hr=S_正常,则
开始
hr:=FileDialog.GetResult(IResult);
如果hr=S_正常,则
开始
IResult.GetDisplayName(SIGDN_FILESYSPATH,FileName);
结果:=文件名;
结束;
结束;
结束;
结束;

结束。

哪个操作系统?WIN x64和WIN X32;只要德尔福支持李