如何确定桌面和网络的图标索引以便在SHGetImageList中使用?

时间:2012-01-28 09:20:27

标签: c# winapi icons pinvoke windows-shell

我能够使用下面包含的API成功提取文件系统驱动器,文件夹和文件的图标。有关帮助我做到这一点的DLL导入等的其他信息可以找到here。通过调用方法GetExtraLargeIconForFolder,我在图标中获得了一个48x48大小的图像。

public enum ImageListIconSize : int
{
    Large = 0x0,
    Small = 0x1,
    ExtraLarge = 0x2,
    Jumbo = 0x4
}

private static IImageList GetSystemImageListHandle(ImageListIconSize size)
{
    IImageList iImageList;
    Guid imageListGuid = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
    int ret = SHGetImageList(
        (int)size,
        ref imageListGuid,
        out iImageList
        );
    return iImageList;
}

public static Icon GetExtraLargeIconForFolder(string path)
{
    SHFILEINFO shinfo = new SHFILEINFO();
    IntPtr retVal = SHGetFileInfo(
        path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo),
        (int)(SHGetFileInfoConstants.SHGFI_SYSICONINDEX |
              SHGetFileInfoConstants.SHGFI_ICON));

    int iconIndex = shinfo.iIcon;
    IImageList iImageList =
        (IImageList)GetSystemImageListHandle(ImageListIconSize.ExtraLarge);
    IntPtr hIcon = IntPtr.Zero;
    if (iImageList != null)
    {
        iImageList.GetIcon(iconIndex,
            (int)ImageListDrawItemConstants.ILD_TRANSPARENT, ref hIcon);
    }

    Icon icon = null;
    if (hIcon != IntPtr.Zero)
    {
        icon = Icon.FromHandle(hIcon).Clone() as Icon;
        DestroyIcon(shinfo.hIcon);
    }
    return icon;
}

在Windows资源管理器中,可以看到桌面,网络和计算机的图标。如何为这些文件系统节点获取正确的图标索引?

1 个答案:

答案 0 :(得分:3)

你快到了。您仍然使用SHGetFileInfo,但您需要在flags参数中传递SHGFI_PIDL

然后,您需要通过传递PIDL而不是路径来指定感兴趣的shell对象。通过致电SHGetSpecialFolderLocation获取PIDL。将CSIDL值传递给此例程,例如CSIDL_DESKTOPCSIDL_DRIVESCSIDL_NETWORK等。