【问题标题】:How to get the shell image index of an object in the shell namespace?如何获取 shell 命名空间中对象的 shell 图像索引?
【发布时间】:2014-08-17 19:52:54
【问题描述】:

我想获取 shell 命名空间中对象的系统图像列表中的索引。

如果这个对象是一个文件,我可以使用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;

除非我没有文件

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

  • Control Panel
  • Homegroup
  • Network

但是我仍然需要在系统图像列表中获取与这个东西对应的图标的索引。我从SHGetFileInfo 开始(因为它支持pidls)。但这分崩离析了。然后我尝试使用IExtractIcon,但结果崩溃了:

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;

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

【问题讨论】:

    标签: shell delphi


    【解决方案1】:

    简单的答案是您将标识对象的绝对 PIDL 传递给SHGetFileInfo。您说您尝试过但没有成功,但这是解决问题的方法。

    您应该返回SHGetFileInfo 并使其工作。看起来你已经有了一个相对的 PI​​DL 并停止了。用ILCombine 做一个绝对的PIDL,你应该回家了。

    如果您没有包含 IShellFolder 的 PIDL,那么您需要阅读此主题:How to obtain the PIDL of an IShellFolder

    【讨论】:

      【解决方案2】:
      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;
      

      【讨论】:

        猜你喜欢
        • 2012-06-12
        • 2022-01-16
        • 2013-06-10
        • 1970-01-01
        • 2017-02-08
        • 2010-10-31
        • 1970-01-01
        • 2013-02-14
        • 2012-08-28
        相关资源
        最近更新 更多