我有一个带有文档列表的listView
。我使用以下方法为每个人分配了一个图标:
private void SetDocumentIcon(ListViewItem item, FileInfo file)
{
Icon iconForFile = Icon.ExtractAssociatedIcon(file.FullName);
if (!documentsIconsImageList.Images.ContainsKey(file.Extension))
{
iconForFile = Icon.ExtractAssociatedIcon(file.FullName);
documentsIconsImageList.Images.Add(file.Extension, iconForFile);
}
item.ImageKey = file.Extension;
}
我尝试对文件夹使用此方法,但失败了。据我了解,问题在于 Icon.ExtractAssociatedIcon
适用于文件而不是文件夹。那么如何提取文件夹的图标呢?
谢谢。
最佳答案
SHGetStockIconInfo
是正确的做法,并且不需要添加不必要的文件 IO。它并不比 SHGetFileInfo
更复杂。
这是一个示例类,其结构与 Evk 的类类似。需要注意的一些重要事项:
- 当您从
SHGetStockIconInfo
(甚至是SHGetFileInfo
)获取图标句柄时, native 图标必须被清理调用DestroyIcon()
,否则会造成资源泄漏。 - 当您使用
Icon.FromHandle()
创建图标时,该对象存储您给它的句柄并将其用于以后的操作。这意味着如果您立即调用DestroyIcon()
然后尝试对刚刚创建的图标执行某些操作,则会导致异常。您可以通过使用Clone()
来避免这种情况获取不依赖于原始 native 句柄的Icon
。
public static class DefaultIcons
{
private static Icon folderIcon;
public static Icon FolderLarge => folderIcon ?? (folderIcon = GetStockIcon(SHSIID_FOLDER, SHGSI_LARGEICON));
private static Icon GetStockIcon(uint type, uint size)
{
var info = new SHSTOCKICONINFO();
info.cbSize = (uint)Marshal.SizeOf(info);
SHGetStockIconInfo(type, SHGSI_ICON | size, ref info);
var icon = (Icon)Icon.FromHandle(info.hIcon).Clone(); // Get a copy that doesn't use the original handle
DestroyIcon(info.hIcon); // Clean up native icon to prevent resource leak
return icon;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHSTOCKICONINFO
{
public uint cbSize;
public IntPtr hIcon;
public int iSysIconIndex;
public int iIcon;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szPath;
}
[DllImport("shell32.dll")]
public static extern int SHGetStockIconInfo(uint siid, uint uFlags, ref SHSTOCKICONINFO psii);
[DllImport("user32.dll")]
public static extern bool DestroyIcon(IntPtr handle);
private const uint SHSIID_FOLDER = 0x3;
private const uint SHGSI_ICON = 0x100;
private const uint SHGSI_LARGEICON = 0x0;
private const uint SHGSI_SMALLICON = 0x1;
}
关于c# - 有没有办法使用 C# 获取 Windows 默认文件夹图标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42910628/