Delphi - 获取文件夹图标

4
我该如何获取特殊文件夹(例如桌面)的图标?
function GetFolderIcon( FName: string ): integer;
var
  FInfo: TSHFileInfo;
begin
  if SHGetFileInfo(pChar(FName), FILE_ATTRIBUTE_NORMAL, FInfo, SizeOf(FInfo),
     SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES or SHGFI_PIDL or SHGFI_ICON or SHGFI_OPENICON ) <> 0 then begin
        Result := FInfo.iIcon
    end
  else
    Result := -1;
end;

GetFolderIcon(GetSpecialFolder(CSIDL_DESKTOP)); 返回 -1

这行代码涉及到IT技术,可能是在获取桌面文件夹图标。但是由于上下文不明确,无法给出更详细的解释。

你看过这个吗?http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_20719182.html - Jerry Dodge
如果-1是一个有效的图标句柄怎么办?实际上不是,但在这里正确的哨兵是0。 - David Heffernan
哦,你也在使用Ini文件吗?这是自定义控件的一部分吗?iniFile的值是多少? - Jerry Dodge
1
@DavidHeffernan: SHFILEINFO.iIcon 是系统图像列表中的索引。0 是有效的索引,但 -1 不是。因此,-1 是此代码的正确返回值。 - Remy Lebeau
好的,我的错误,抱歉,谢谢。 - David Heffernan
1个回答

9

CSIDL_DESKTOP是“表示Windows桌面的虚拟文件夹,命名空间的根目录”。因此,它没有文件系统路径可以传递给SHGetFileInfo()。你可能想到的应该是CSIDL_DESKTOPDIRECTORY,它是“用于在桌面上物理存储文件对象的文件系统目录(不要与桌面文件夹本身混淆)”:

GetFolderIcon(GetSpecialFolder(CSIDL_DESKTOPDIRECTORY));

当使用SHGetFileInfo()时,您可以指定SHGFI_PIDL标志,以便传递PIDL而不是文件系统路径。这允许查询虚拟项。您的代码已经使用了SHGFI_PIDL,但没有使用任何PIDL,这意味着您一开始就错误地使用了SHGetFileInfo()
尝试这样做:
uses
  ..., ShlObj, SHFolder;

function GetSpecialFolderPath(FolderID: Integer): String;
var
  Path: array[0..MAX_PATH] of Char;
begin
  if SHGetFolderPath(0, FolderID, nil, SHGFP_TYPE_CURRENT, Path) = 0 then
    Result := Path
  else
    Result := '';
end;

function GetSpecialFolderPidl(FolderID: Integer): PItemIDList;
begin
  Result := nil;
  SHGetSpecialFolderLocation(0, FolderID, Result);
end;

function GetFolderIcon( FName: String ): integer; overload;
var
  FInfo: TSHFileInfo;
begin
  ZeroMemory(@FInfo, SizeOf(FInfo));
  if SHGetFileInfo(PChar(FName), FILE_ATTRIBUTE_NORMAL, FInfo, SizeOf(FInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_ICON or SHGFI_OPENICON ) <> 0 then
  begin
    Result := FInfo.iIcon;
    if FInfo.hIcon <> 0 then DestroyIcon(FInfo.hIcon);
  end else
    Result := -1;
end;

function GetFolderIcon( Pidl: PItemIDList ): integer; overload;
var
  FInfo: TSHFileInfo;
begin
    if SHGetFileInfo(PChar(Pidl), FILE_ATTRIBUTE_NORMAL, FInfo, SizeOf(FInfo), SHGFI_PIDL or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_ICON or SHGFI_OPENICON ) <> 0 then
  begin
    Result := FInfo.iIcon;
    if FInfo.hIcon <> 0 then DestroyIcon(FInfo.hIcon);
  end
  else
    Result := -1;
end;

var
  Icon: Integer;
  Pidl: PItemIDList;
begin
  Icon := -1;
  Pidl := GetSpecialFolderPidl(CSIDL_DESKTOP);
  if Pidl <> nil then
  try
    Icon := GetFolderIcon(Pidl);
  finally
    CoTaskMemFree(Pidl);
  end;
end;

var
  Icon: Integer;
  Path: string;
begin
  Icon := -1;
  Path := GetSpecialFolderPath(CSIDL_DESKTOPDIRECTORY);
  if Path <> '' then
    Icon := GetFolderIcon(Path);
end;

感谢您的回答。 - RepeatUntil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接