如何在外壳名称空间中获取对象的外壳图像索引? [英] How to get the shell image index of an object in the shell namespace?

查看:56
本文介绍了如何在外壳名称空间中获取对象的外壳图像索引?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在shell名称空间中的对象的系统映像列表中获取索引.

I want to get the index in the system imagelist of an object in the shell namespace.

如果该对象是文件,我可以使用 SHGetFileInfo :

If this object was a file i could use SHGetFileInfo:

function GetFileImageIndex(const Filename: string): Integer;
var
   sfi: TSHFileInfo;
begin
   SHGetFileInfo(PChar(Filename), FILE_ATTRIBUTE_NORMAL, sfi, SizeOf(sfi), 
         SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX);
   Result := sfi.iIcon;
end;

除了我没有文件

我拥有的东西在硬盘驱动器上不作为文件夹或文件存在,例如:

The thing i have doesn't exist on the hard-drive as a folder or file, e.g.:

  • 控制面板
  • 家庭组
  • 网络

但是我仍然需要在与此图像相对应的图标的系统图像列表中获取索引.我从 SHGetFileInfo 开始(因为它支持pidls).但这崩溃了.然后我尝试使用 IExtractIcon ,但这失败了:

But i still need to get the index in the system imagelist of the icon that corresponds to this thing. I started with SHGetFileInfo (as it supports pidls). But that fell apart. Then i tried using IExtractIcon, but that fell apart:

function GetObjectImageIndex(ParentFolder: IShellFolder; const ChildPidl: PItemIDList): Integer;
//var
//  sfi: TSHFileInfo;

//  extractIcon: IExtractIcon;
//  iconFile: WideString;
//  iconIndexInFile: Integer;
//  flags: Cardinal;
begin
    {
        This function is the shell namespace equivalent of GetFileImageIndex helper function.
    }
(*
    Won't work (MSDN: "The PIDL must be a fully qualified PIDL. Relative PIDLs are not allowed.")
    SHGetFileInfo(PWideChar(ChildPidl), FILE_ATTRIBUTE_NORMAL,
            sfi, SizeOf(sfi),
            SHGFI_PIDL or SHGFI_SYSICONINDEX);
*)

(*
    Won't work. Doesn't return an index into the system imagelist
    ParentFolder.GetUIObjectOf(0, 1, ChildPidl, IExtractIcon, nil, {out}extractIcon);
    SetLength(iconFile, MAX_PATH);
    extractIcon.GetIconLocation(0, PWideChar(iconFile), Length(iconFile), iconIndexInFile, {out}flags);
*)

    Result := -1; //TODO: Figure out how to do it.
end;

在该文件夹中给出 IShellFolder pidl ,我如何在该东西的系统映像列表中获取图标?

Given an IShellFolder and a pidl in that folder, how do i get the icon in the system imagelist of that thing?

推荐答案

function CreateGlobalChildIDList(AParentFolder: IShellFolder; const AChildIDList: PItemIDList): PItemIDList; forward;

function GetObjectImageIndex(AParentFolder: IShellFolder; const AChildIDList: PItemIDList): Integer;
var
  ShellIcon: IShellIcon;
  ChildIDList: PItemIDList;
  FileInfo: TSHFileInfo;
begin
  try
    Result := -1;
    try
      OleCheck(AParentFolder.QueryInterface(IShellIcon, ShellIcon));
      try
        OleCheck(ShellIcon.GetIconOf(AChildIDList, GIL_FORSHELL, Result));
      finally
        ShellIcon := nil;
      end;
    except
      Result := -1;
    end;

    if Result = -1 then
      begin
        ChildIDList := CreateGlobalChildIDList(AParentFolder, AChildIDList);
        try
          ZeroMemory(@FileInfo, SizeOf(FileInfo));
          SHGetFileInfo(PWideChar(ChildIDList), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo), SHGFI_PIDL or SHGFI_SYSICONINDEX);
          Result := FileInfo.iIcon;
        finally
          CoTaskMemFree(ChildIDList);
        end;
      end;
  except
    Result := -1;
  end;
end;

  function CretaeGlobalChildIDList(AParentFolder: IShellFolder; const AChildIDList: PItemIDList): PItemIDList;
  var
    PersistFolder2: IPersistFolder2;
    PersistIDList: IPersistIDList;
    ParentIDList: PItemIDList;
  begin
    if Succeeded(AParentFolder.QueryInterface(IPersistFolder2, PersistFolder2)) then
      try
        OleCheck(PersistFolder2.GetCurFolder(ParentIDList));
        try
          Result := ILCombine(ParentIDList, AChildIDList);
        finally
          CoTaskMemFree(ParentIDList);
        end;
      finally
        PersistFolder2 := nil;
      end
    else
      if Succeeded(AParentFolder.QueryInterface(IPersistIDList, PersistIDList)) then
        try
          OleCheck(PersistIDList.GetIDList(ParentIDList));
          try
            Result := ILCombine(ParentIDList, AChildIDList);
          finally
            CoTaskMemFree(ParentIDList);
          end;
        finally
          PersistIDList := nil;
        end
      else
        raise Exception.Create('Cannot create PIDL');
  end;

这篇关于如何在外壳名称空间中获取对象的外壳图像索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆