我已经知道如何通过P / Invoking到SHGetFileInfo
获取特定路径的文件系统相关图标。但这需要一条实际的道路。另外,它只返回一个图标。
我想知道的是双重的。
是否有这样的方式或我是否必须简单地将它传递给SHGetFileInfo
的“虚拟”路径而忘记有两个状态?
作为参考,我正在寻找这个,因为我们正在构建一个自定义树来显示某些文件系统对象,但是它们将显示在几个应用程序定义的组下面,我们希望这些组与图像文件夹相同。用于实际目录的那些。
答案 0 :(得分:1)
是的,你可以。
免责声明(TL,DR):
不要因为这个答案的长度而生我的气。 98% 它只是简单的枚举代码,你只需要复制粘贴 (我喜欢把所有东西放在同一个地方和时间)
请注意,已知System.Drawing命名空间中的图标操作容易出现内存泄漏。我不明白为什么在使用DestroyIcon(handle)
这些年来没有做过任何改变(这也会使你的图标无效到零大小的0x0图标),而你应该使用代码中其他地方的那个图标......
...另外,它只返回一个图标......
我所知道的托管或非托管方法没有一种方法可以返回一个包含多种格式和大小的图标。要拥有不同的图标,您必须逐个调用它们,或者通过解析包含图标变体的文件来创建它们中的每一个。
顺便说一下,我只是一个业余程序员,他已经找到了解读整个Icon乱七八糟的方法。我在这里写的是初级水平。随意纠正我犯的任何错误(我确定有)。我很惊讶找到涉及图标的UI任务的答案是多么困难。
基本上,您必须:
SHSTOCKICONID
结构SHGetStockIconInfo(...)
,文件夹图标ID(枚举成员)和图标选项您可以在系统的库存图标(包含文件夹图标)中找到指向您正在寻找的图标的指针
顺便说一下,该方法还为您提供(通过结构,如果正确初始化)有用的信息,例如包含系统图标的文件的路径,以及该文件中的索引,但是因为您已经有了指针在图标上,您所要做的就是创建一个图标:
Icon icon = Icon.FromHandle(handle)
// And here is where you don't really know how to destroy the handle...
小心!!!
API和一些枚举值对某些值不起作用 平台。简而言之,Windows Vista之前的一切都很少 根本没有支持。此外,几乎所有东西都是桌面 仅限应用!顺便说一句,事情可能无法在Windows CE上运行。Windows 7及更高版本具有未涵盖的扩展功能 这个答案。
API调用的已知替代方案:WPF和VectorIcons。这里没有涉及。
使用以下命名空间:
using System.Runtime.InteropServices; // [DllImport()], [MarshalAs()]
using System.Runtime.CompilerServices // [Extension()]
一个非常重要的声明: DestroyIcon()
方法。
/// <summary>
/// Destroys an icon and frees any memory the icon occupied.
/// </summary>
/// <param name="hIcon">A handle to the icon to be destroyed. The icon must not be in use.</param>
/// <returns>If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.</returns>
/// <remarks>To get extended error information, call GetLastError.</remarks>
[DllImport("user32.dll", EntryPoint = "DestroyIcon", SetLastError = true)]
private static extern bool DestroyIcon(IntPtr hIcon);
所以,这是你的Shell32
声明(由PInvoke提供,添加了XML注释):
/// <summary>
/// Retrieves information about a stock icon.
/// </summary>
/// <param name="siid">One of the values from the SHSTOCKICONID enumeration that specifies which icon should be retrieved.</param>
/// <param name="uFlags">A combination of zero or more of the following flags that specify which information is requested.</param>
/// <param name="psii">A pointer to a SHSTOCKICONINFO structure. When this function is called, the cbSize member of this structure needs to be set to the size of the SHSTOCKICONINFO structure. When this function returns, contains a pointer to a SHSTOCKICONINFO structure that contains the requested information.</param>
/// <returns>If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
/// <remarks>If this function returns an icon handle in the hIcon member of the SHSTOCKICONINFO structure pointed to by psii, you are responsible for freeing the icon with DestroyIcon when you no longer need it.</remarks>
[DllImport("Shell32.dll", SetLastError = false)]
private static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii);
以下是SHSTOCKICONINFO
结构的外观(添加了XML注释):
/// <summary>
/// Receives information used to retrieve a stock Shell icon. This structure is used in a call SHGetStockIconInfo.
/// </summary>
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHSTOCKICONINFO
{
/// <summary>
/// The size of this structure, in bytes.
/// </summary>
public UInt32 cbSize;
/// <summary>
/// When SHGetStockIconInfo is called with the SHGSI_ICON flag, this member receives a handle to the icon.
/// </summary>
public IntPtr hIcon;
/// <summary>
/// When SHGetStockIconInfo is called with the SHGSI_SYSICONINDEX flag, this member receives the index of the image in the system icon cache.
/// </summary>
public Int32 iSysIconIndex;
/// <summary>
/// When SHGetStockIconInfo is called with the SHGSI_ICONLOCATION flag, this member receives the index of the icon in the resource whose path is received in szPath.
/// </summary>
public Int32 iIcon;
/// <summary>
/// When SHGetStockIconInfo is called with the SHGSI_ICONLOCATION flag, this member receives the path of the resource that contains the icon. The index of the icon within the resource is received in iIcon.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string szPath;
}
由于MAX_PATH
结构中的 SHSTOCKICONINFO
未定义,因此它是:
const Int32 MAX_PATH = 260;
SHGSI
是一个枚举,用于定义您要提交的选项以及对SHGetStockIconInfo()
的调用
/// <summary>
/// UInt Enumeration with Flags that specify which information is requested.
/// </summary>
[Flags()]
public enum SHGSI : UInt32
{
/// <summary>
/// The szPath and iIcon members of the SHSTOCKICONINFO structure receive the path and icon index of the requested icon, in a format suitable for passing to the ExtractIcon function. The numerical value of this flag is zero, so you always get the icon location regardless of other flags.
/// </summary>
SHGSI_ICONLOCATION = 0,
/// <summary>
/// The hIcon member of the SHSTOCKICONINFO structure receives a handle to the specified icon.
/// </summary>
SHGSI_ICON = 0x100,
/// <summary>
/// The iSysImageImage member of the SHSTOCKICONINFO structure receives the index of the specified icon in the system imagelist.
/// </summary>
SHGSI_SYSICONINDEX = 0x4000,
/// <summary>
/// Modifies the SHGSI_ICON value by causing the function to add the link overlay to the file's icon.
/// </summary>
SHGSI_LINKOVERLAY = 0x8000,
/// <summary>
/// Modifies the SHGSI_ICON value by causing the function to blend the icon with the system highlight color.
/// </summary>
SHGSI_SELECTED = 0x10000,
/// <summary>
/// Modifies the SHGSI_ICON value by causing the function to retrieve the large version of the icon, as specified by the SM_CXICON and SM_CYICON system metrics.
/// </summary>
SHGSI_LARGEICON = 0x0,
/// <summary>
/// Modifies the SHGSI_ICON value by causing the function to retrieve the small version of the icon, as specified by the SM_CXSMICON and SM_CYSMICON system metrics.
/// </summary>
SHGSI_SMALLICON = 0x1,
/// <summary>
/// Modifies the SHGSI_LARGEICON or SHGSI_SMALLICON values by causing the function to retrieve the Shell-sized icons rather than the sizes specified by the system metrics.
/// </summary>
SHGSI_SHELLICONSIZE = 0x4
}
SHSTOCKICONID
是一个包含很多值的枚举。希望你不会感到头疼......:P - 请乘坐本枚举的MSDN constants来了解图标的外观。
/// <summary>
/// Used by SHGetStockIconInfo to identify which stock system icon to retrieve.
/// </summary>
/// <remarks>SIID_INVALID, with a value of -1, indicates an invalid SHSTOCKICONID value.</remarks>
public enum SHSTOCKICONID : UInt32
{
/// <summary>
/// Document of a type with no associated application.
/// </summary>
SIID_DOCNOASSOC = 0,
/// <summary>
/// Document of a type with an associated application.
/// </summary>
SIID_DOCASSOC = 1,
/// <summary>
/// Generic application with no custom icon.
/// </summary>
SIID_APPLICATION = 2,
/// <summary>
/// Folder (generic, unspecified state).
/// </summary>
SIID_FOLDER = 3,
/// <summary>
/// Folder (open).
/// </summary>
SIID_FOLDEROPEN = 4,
/// <summary>
/// 5.25-inch disk drive.
/// </summary>
SIID_DRIVE525 = 5,
/// <summary>
/// 3.5-inch disk drive.
/// </summary>
SIID_DRIVE35 = 6,
/// <summary>
/// Removable drive.
/// </summary>
SIID_DRIVEREMOVE = 7,
/// <summary>
/// Fixed drive (hard disk).
/// </summary>
SIID_DRIVEFIXED = 8,
/// <summary>
/// Network drive (connected).
/// </summary>
SIID_DRIVENET = 9,
/// <summary>
/// Network drive (disconnected).
/// </summary>
SIID_DRIVENETDISABLED = 10,
/// <summary>
/// CD drive.
/// </summary>
SIID_DRIVECD = 11,
/// <summary>
/// RAM disk drive.
/// </summary>
SIID_DRIVERAM = 12,
/// <summary>
/// The entire network.
/// </summary>
SIID_WORLD = 13,
/// <summary>
/// A computer on the network.
/// </summary>
SIID_SERVER = 15,
/// <summary>
/// A local printer or print destination.
/// </summary>
SIID_PRINTER = 16,
/// <summary>
/// The Network virtual folder (FOLDERID_NetworkFolder/CSIDL_NETWORK).
/// </summary>
SIID_MYNETWORK = 17,
/// <summary>
/// The Search feature.
/// </summary>
SIID_FIND = 22,
/// <summary>
/// The Help and Support feature.
/// </summary>
SIID_HELP = 23,
// OVERLAYS...
/// <summary>
/// Overlay for a shared item.
/// </summary>
SIID_SHARE = 28,
/// <summary>
/// Overlay for a shortcut.
/// </summary>
SIID_LINK = 29,
/// <summary>
/// Overlay for items that are expected to be slow to access.
/// </summary>
SIID_SLOWFILE = 30,
// MORE ICONS...
/// <summary>
/// The Recycle Bin (empty).
/// </summary>
SIID_RECYCLER = 31,
/// <summary>
/// The Recycle Bin (not empty).
/// </summary>
SIID_RECYCLERFULL = 32,
/// <summary>
/// Audio CD media.
/// </summary>
SIID_MEDIACDAUDIO = 40,
/// <summary>
/// Security lock.
/// </summary>
SIID_LOCK = 47,
/// <summary>
/// A virtual folder that contains the results of a search.
/// </summary>
SIID_AUTOLIST = 49,
/// <summary>
/// A network printer.
/// </summary>
SIID_PRINTERNET = 50,
/// <summary>
/// A server shared on a network.
/// </summary>
SIID_SERVERSHARE = 51,
/// <summary>
/// A local fax printer.
/// </summary>
SIID_PRINTERFAX = 52,
/// <summary>
/// A network fax printer.
/// </summary>
SIID_PRINTERFAXNET = 53,
/// <summary>
/// A file that receives the output of a Print to file operation.
/// </summary>
SIID_PRINTERFILE = 54,
/// <summary>
/// A category that results from a Stack by command to organize the contents of a folder.
/// </summary>
SIID_STACK = 55,
/// <summary>
/// Super Video CD (SVCD) media.
/// </summary>
SIID_MEDIASVCD = 56,
/// <summary>
/// A folder that contains only subfolders as child items.
/// </summary>
SIID_STUFFEDFOLDER = 57,
/// <summary>
/// Unknown drive type.
/// </summary>
SIID_DRIVEUNKNOWN = 58,
/// <summary>
/// DVD drive.
/// </summary>
SIID_DRIVEDVD = 59,
/// <summary>
/// DVD media.
/// </summary>
SIID_MEDIADVD = 60,
/// <summary>
/// DVD-RAM media.
/// </summary>
SIID_MEDIADVDRAM = 61,
/// <summary>
/// DVD-RW media.
/// </summary>
SIID_MEDIADVDRW = 62,
/// <summary>
/// DVD-R media.
/// </summary>
SIID_MEDIADVDR = 63,
/// <summary>
/// DVD-ROM media.
/// </summary>
SIID_MEDIADVDROM = 64,
/// <summary>
/// CD+ (enhanced audio CD) media.
/// </summary>
SIID_MEDIACDAUDIOPLUS = 65,
/// <summary>
/// CD-RW media.
/// </summary>
SIID_MEDIACDRW = 66,
/// <summary>
/// CD-R media.
/// </summary>
SIID_MEDIACDR = 67,
/// <summary>
/// A writeable CD in the process of being burned.
/// </summary>
SIID_MEDIACDBURN = 68,
/// <summary>
/// Blank writable CD media.
/// </summary>
SIID_MEDIABLANKCD = 69,
/// <summary>
/// CD-ROM media.
/// </summary>
SIID_MEDIACDROM = 70,
/// <summary>
/// An audio file.
/// </summary>
SIID_AUDIOFILES = 71,
/// <summary>
/// An image file.
/// </summary>
SIID_IMAGEFILES = 72,
/// <summary>
/// A video file.
/// </summary>
SIID_VIDEOFILES = 73,
/// <summary>
/// A mixed (media) file.
/// </summary>
SIID_MIXEDFILES = 74,
/// <summary>
/// Folder back. Represents the background Fold of a Folder.
/// </summary>
SIID_FOLDERBACK = 75,
/// <summary>
/// Folder front. Represents the foreground Fold of a Folder.
/// </summary>
SIID_FOLDERFRONT = 76,
/// <summary>
/// Security shield.
/// </summary>
/// <remarks>Use for UAC prompts only. This Icon doesn't work on all purposes.</remarks>
SIID_SHIELD = 77,
/// <summary>
/// Warning (Exclamation mark).
/// </summary>
SIID_WARNING = 78,
/// <summary>
/// Informational (Info).
/// </summary>
SIID_INFO = 79,
/// <summary>
/// Error (X).
/// </summary>
SIID_ERROR = 80,
/// <summary>
/// Key.
/// </summary>
SIID_KEY = 81,
/// <summary>
/// Software.
/// </summary>
SIID_SOFTWARE = 82,
/// <summary>
/// A UI item, such as a button, that issues a rename command.
/// </summary>
SIID_RENAME = 83,
/// <summary>
/// A UI item, such as a button, that issues a delete command.
/// </summary>
SIID_DELETE = 84,
/// <summary>
/// Audio DVD media.
/// </summary>
SIID_MEDIAAUDIODVD = 85,
/// <summary>
/// Movie DVD media.
/// </summary>
SIID_MEDIAMOVIEDVD = 86,
/// <summary>
/// Enhanced CD media.
/// </summary>
SIID_MEDIAENHANCEDCD = 87,
/// <summary>
/// Enhanced DVD media.
/// </summary>
SIID_MEDIAENHANCEDDVD = 88,
/// <summary>
/// Enhanced DVD media.
/// </summary>
SIID_MEDIAHDDVD = 89,
/// <summary>
/// High definition DVD media in the Blu-ray Disc™ format.
/// </summary>
SIID_MEDIABLURAY = 90,
/// <summary>
/// Video CD (VCD) media.
/// </summary>
SIID_MEDIAVCD = 91,
/// <summary>
/// DVD+R media.
/// </summary>
SIID_MEDIADVDPLUSR = 92,
/// <summary>
/// DVD+RW media.
/// </summary>
SIID_MEDIADVDPLUSRW = 93,
/// <summary>
/// A desktop computer.
/// </summary>
SIID_DESKTOPPC = 94,
/// <summary>
/// A mobile computer (laptop).
/// </summary>
SIID_MOBILEPC = 95,
/// <summary>
/// The User Accounts Control Panel item.
/// </summary>
SIID_USERS = 96,
/// <summary>
/// Smart media.
/// </summary>
SIID_MEDIASMARTMEDIA = 97,
/// <summary>
/// CompactFlash media.
/// </summary>
SIID_MEDIACOMPACTFLASH = 98,
/// <summary>
/// A cell phone.
/// </summary>
SIID_DEVICECELLPHONE = 99,
/// <summary>
/// A digital camera.
/// </summary>
SIID_DEVICECAMERA = 100,
/// <summary>
/// A digital video camera.
/// </summary>
SIID_DEVICEVIDEOCAMERA = 101,
/// <summary>
/// An audio player.
/// </summary>
SIID_DEVICEAUDIOPLAYER = 102,
/// <summary>
/// Connect to network.
/// </summary>
SIID_NETWORKCONNECT = 103,
/// <summary>
/// The Network and Internet Control Panel item.
/// </summary>
SIID_INTERNET = 104,
/// <summary>
/// A compressed file with a .zip file name extension.
/// </summary>
SIID_ZIPFILE = 105,
/// <summary>
/// The Additional Options Control Panel item.
/// </summary>
SIID_SETTINGS = 106,
/// <summary>
/// Windows Vista with Service Pack 1 (SP1) and later. High definition DVD drive (any type - HD DVD-ROM, HD DVD-R, HD-DVD-RAM) that uses the HD DVD format.
/// </summary>
SIID_DRIVEHDDVD = 132,
/// <summary>
/// Windows Vista with SP1 and later. High definition DVD drive (any type - BD-ROM, BD-R, BD-RE) that uses the Blu-ray Disc format.
/// </summary>
SIID_DRIVEBD = 133,
/// <summary>
/// Windows Vista with SP1 and later. High definition DVD-ROM media in the HD DVD-ROM format.
/// </summary>
SIID_MEDIAHDDVDROM = 134,
/// <summary>
/// Windows Vista with SP1 and later. High definition DVD-R media in the HD DVD-R format.
/// </summary>
SIID_MEDIAHDDVDR = 135,
/// <summary>
/// Windows Vista with SP1 and later. High definition DVD-RAM media in the HD DVD-RAM format.
/// </summary>
SIID_MEDIAHDDVDRAM = 136,
/// <summary>
/// Windows Vista with SP1 and later. High definition DVD-ROM media in the Blu-ray Disc BD-ROM format.
/// </summary>
SIID_MEDIABDROM = 137,
/// <summary>
/// Windows Vista with SP1 and later. High definition write-once media in the Blu-ray Disc BD-R format.
/// </summary>
SIID_MEDIABDR = 138,
/// <summary>
/// Windows Vista with SP1 and later. High definition read/write media in the Blu-ray Disc BD-RE format.
/// </summary>
SIID_MEDIABDRE = 139,
/// <summary>
/// Windows Vista with SP1 and later. A cluster disk array.
/// </summary>
SIID_CLUSTEREDDRIVE = 140,
/// <summary>
/// The highest valid value in the enumeration. Values over 160 are Windows 7-only icons.
/// </summary>
SIID_MAX_ICONS = 175
}
我们走了!
创建一个实用程序包装器。根据您的要求,班级名称和成员会有所不同。以下是我已经完成的工作,但您可以随意进行所有必要的修改:
public class IconUtils
{
// copy DLL declarations above here...
// ...
// and copy again the XML summary here.
public static bool DestroyIconH(IntPtr iconHandle)
{
return DestroyIcon(iconHandle);
}
/// <summary>
/// Gets the Pointer to the (stock) Icon associated to the specified ID.
/// </summary>
/// <param name="StockIconID">Icon ID among the defined Stock ones.</param>
/// <returns>The Pointer to the retrieved Icon. If no Icon were found, an empty Pointer is returned.</returns>
private static IntPtr GetShellIconPointer(SHSTOCKICONID StockIconID, SHGSI IconOptions)
{
SHSTOCKICONINFO StkIconInfo = new SHSTOCKICONINFO();
StkIconInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(SHSTOCKICONINFO)));
if (SHGetStockIconInfo(StockIconID, IconOptions, StkIconInfo) == 0) {
return StkIconInfo.hIcon;
}
return IntPtr.Zero;
}
/// <summary>
/// Gets the (stock) Icon associated to the specified ID.
/// </summary>
/// <param name="StockIconID">Icon ID among the defined Stock ones.</param>
/// <returns>The (stock) Icon. If no Icon were found, Null is returned.</returns>
/// <remarks>WARNING ! Caller is responsible of calling Dispose() on the returned Icon.</remarks>
public static Icon GetSystemIcon(SHSTOCKICONID stockIconID, SHGSI iconOptions)
{
IntPtr iconPointer = GetShellIconPointer(stockIconID, iconOptions);
if (iconPointer != IntPtr.Zero) {
Icon actualIcon = Icon.FromHandle(iconPointer);
Icon iconCopy = (System.Drawing.Icon)actualIcon.Clone();
actualIcon.Dispose();
DestroyIcon(iconPointer);
/*
Honestly, I'm unsure of what I'm doing here :-(
If I get rid of either actualIcon or iconCopy,
and don't make a copy of it, I get a 0x0 Icon.
If I don't call DestroyIcon(h), I get a memory leak.
I highly doubt a memory leak won't occur even with the trick above,
but heh! >:-D honestly I don't care since
everything related to Icon retrieval in Windows
appears to me a very bad design pattern in the first place.
*/
return iconCopy;
} else {
return null;
}
}
}
还为System.Drawing.Bitmap
创建扩展方法。默认的CreateThumbnail()并不适合我的需要:
/// <summary>
/// Creates a Thumbnail of the Bitmap.
/// </summary>
/// <param name="sourceBitmap">Source Bitmap.</param>
/// <param name="width">Width for the Tumbnail.</param>
/// <param name="height">Height for the Tumbnail.</param>
/// <returns>Returns the created Thumbnail.</returns>
[Extension()]
public Bitmap CreateThumbnail(this Bitmap sourceBitmap, Int32 width, Int32 height)
{
if (sourceBitmap == null) {
return null; // Eat Exception !
} else {
if ((width > 0) && (height > 0)) {
Rectangle layoutRectangle = new Rectangle(0, 0, width, height);
Bitmap thumbnailBitmap = new Bitmap(width, height, sourceBitmap.PixelFormat);
using (Graphics bmpGrphics = thumbnailBitmap.CreateGraphics()) {
bmpGrphics.DrawImage(sourceBitmap, layoutRectangle);
}
return thumbnailBitmap;
} else {
return null;
}
}
}
工作原理:
在代码中的某处,您可以使用实用程序包装器:
SHSTOCKICONID
值之一)这是电话:
// You're looking for a 16x16 opened folder icon :
Icon icon16 = IconUtils.GetShellIcon(SHSTOCKICONID.SIID_FOLDEROPEN, SHGSI.SHGSI_ICON Or SHGSI.SHGSI_SMALLICON);
// You're looking for a 32x32 default state folder icon :
Icon icon32 = IconUtils.GetShellIcon(SHSTOCKICONID.SIID_FOLDER, SHGSI.SHGSI_ICON Or SHGSI.SHGSI_LARGEICON);
上面的PInvoke链接建议您使用SHGSI.SHGSI_SMALLICON Or SHGSI.SHGSI_LARGEICON
,但这不起作用(至少在我的系统上)。似乎未能通过SHGSI_ICON标志将阻止图标句柄在结构中正确设置。而且我根本没有图标。
SHSTOCKICONID.SIID_FOLDER
和SHSTOCKICONID.SIID_FOLDEROPEN
由完全相同的图标表示。 MS失败恕我直言!有时,我只是使用SHSTOCKICONID.SIID_FOLDERBACK
来显示已关闭状态,但您可以自由选择适合您(和用户)需求的状态。
额外:
现在你有了图标,我想你想在某个地方使用它们,比如将它们存储在两个ImageList(imgList16
和imgList32
- 或类似的)中。通常,您将始终同时拥有16x16和32x32版本,并以适合您显示的格式返回(如MS所宣传的那样)。但我不指望这一点,我总是检查我有两个:
// Get the two icons...
Icon dirIcon16 = Icon_Class.GetShellIcon(SHSTOCKICONID.SIID_FOLDEROPEN, SHGSI.SHGSI_ICON | SHGSI.SHGSI_SMALLICON);
Icon dirIcon32 = Icon_Class.GetShellIcon(SHSTOCKICONID.SIID_FOLDEROPEN, SHGSI.SHGSI_ICON | SHGSI.SHGSI_LARGEICON);
// Make sure you have both...
if (DirIcon16 == null) {
if (DirIcon32 == null) {
// both are missing... use a placeholder bitmap instead.
// do the necessary changes and checks...
} else {
// at least the 32x32 is available.
Bitmap iconBitmap32 = dirIcon32.ToBitmap();
Bitmap iconBitmap16 = iconBitmap32.CreateThumbnail(16, 16);
// now you can add both in two ImageList...
imgList16.Images.Add("Directory_Opened", iconBitmap16);
imgList32.Images.Add("Directory_Opened", iconBitmap32);
dirIcon32.Dispose();
}
} else {
Bitmap iconBitmap16 = dirIcon16.ToBitmap();
imgList16.Images.Add("Directory_Opened", iconBitmap16);
if (dirIcon32 == null) {
Bitmap iconBitmap32 = iconBitmap16.CreateThumbnail(32, 32);
imgList32.Images.Add("Directory_Opened", iconBitmap32);
} else {
Bitmap iconBitmap32 = dirIcon32.ToBitmap();
imgList32.Images.Add("Directory_Opened", iconBitmap32);
dirIcon32.Dispose();
}
dirIcon16.Dispose();
}
// hence the extension above.
如您所见,所有这些只为您提供16x16和32x32图标。多年来,这是Windows的一个已知限制。应用程序(和几个Windows对话框)如何能够获得其他格式是一个完全不同的主题。您可以首先使用上述所有内容来检索包含图标(库,单个图标或可执行文件)及其在资源中的索引的文件的路径。我建议您使用SHGSI
枚举来检索这些信息。
然后,您必须在自己提取必要的字节或流后实现 IconParser (处理非标准大小的图标,考虑大小超过255像素的图标,它们在标题中没有任何有效的宽度/高度数据,要小心PNG压缩格式,在解析chuncks时要小心负值,不要忘记尽可能释放资源等等。)
嗯,那说,我糟透了资源管理...抱歉:/
祝你好运!答案 1 :(得分:0)
是的,可以在调用SHGetFileInfo
时指定虚拟路径。将pszPath参数设置为c:\foo
。在uFlags参数中包含SHGFI_USEFILEATTRIBUTES
以及图标标记,这告诉Windows没有要加载的真实文件(还包括SHGFI_OPENICON
以获取打开的文件夹)。在dwFileAttributes参数中包含FILE_ATTRIBUTE_DIRECTORY
,以便Windows知道您需要文件夹数据。
另见: