diff --git a/Windows.Shell/ShellImageList.cs b/Windows.Shell/ShellImageList.cs
index 1ac94f45..c078e859 100644
--- a/Windows.Shell/ShellImageList.cs
+++ b/Windows.Shell/ShellImageList.cs
@@ -1,39 +1,58 @@
using System;
using System.Drawing;
-using System.IO;
-using System.Runtime.InteropServices;
using static Vanara.PInvoke.ComCtl32;
using static Vanara.PInvoke.Shell32;
-using static Vanara.PInvoke.User32_Gdi;
namespace Vanara.Windows.Shell
{
+ /// Used to determine the size of the icon returned by .
+ public enum ShellImageSize
+ {
+ ///
+ /// The image size is normally 32x32 pixels. However, if the Use large icons option is selected from the Effects section of the Appearance tab in
+ /// Display Properties, the image is 48x48 pixels.
+ ///
+ Large = SHIL.SHIL_LARGE,
+ /// The image is the Shell standard small icon size of 16x16, but the size can be customized by the user.
+ Small = SHIL.SHIL_SMALL,
+ /// The image is the Shell standard extra-large icon size. This is typically 48x48, but the size can be customized by the user.
+ ExtraLarge = SHIL.SHIL_EXTRALARGE,
+ /// Windows Vista and later. The image is normally 256x256 pixels.
+ Jumbo = SHIL.SHIL_JUMBO
+ }
+
+ /// Represents the System Image List holding images for all shell icons.
public static class ShellImageList
{
- private static IntPtr largeImageListHandle;
- private static IntPtr smallImageListHandle;
+ private static int shfiSz = SHFILEINFO.Size;
- static ShellImageList()
+ /// Gets the system icon for the given file name or extension.
+ /// The file name or extension.
+ /// Size of the icon.
+ /// An instance if found; otherwise .
+ public static Icon GetSystemIcon(string fileNameOrExtension, ShellImageSize iconSize = ShellImageSize.Large)
{
- const SHGFI baseFlags = SHGFI.SHGFI_USEFILEATTRIBUTES | SHGFI.SHGFI_SYSICONINDEX;
-
- var shfiSz = Marshal.SizeOf(typeof(SHFILEINFO));
-
- var shfiSmall = new SHFILEINFO();
- smallImageListHandle = SHGetFileInfo(".txt", FileAttributes.Normal, ref shfiSmall, shfiSz, baseFlags | SHGFI.SHGFI_SMALLICON);
-
- var shfiLarge = new SHFILEINFO();
- largeImageListHandle = SHGetFileInfo(".txt", FileAttributes.Normal, ref shfiLarge, shfiSz, baseFlags | SHGFI.SHGFI_LARGEICON);
+ var shfi = new SHFILEINFO();
+ var hImageList = SHGetFileInfo(fileNameOrExtension, 0, ref shfi, shfiSz, SHGFI.SHGFI_SYSICONINDEX | (iconSize == ShellImageSize.Small ? SHGFI.SHGFI_SMALLICON : 0));
+ if (hImageList == IntPtr.Zero) return null;
+ if (iconSize <= ShellImageSize.Small)
+ return IconLocation.GetClonedIcon(ImageList_GetIcon(hImageList, shfi.iIcon, IMAGELISTDRAWFLAGS.ILD_TRANSPARENT));
+ SHGetImageList((SHIL)iconSize, typeof(IImageList).GUID, out var il).ThrowIfFailed();
+ return IconLocation.GetClonedIcon(il.GetIcon(shfi.iIcon, IMAGELISTDRAWFLAGS.ILD_TRANSPARENT));
}
- public static Icon GetIcon(int index, bool small = true)
+ /// Gets the Shell icon for the given file name or extension.
+ /// The file name or extension .
+ /// Flags to specify the type of the icon to retrieve. This uses the method and can only retrieve small or large icons.
+ /// An instance if found; otherwise .
+ public static Icon GetFileIcon(string fileNameOrExtension, ShellIconType iconType = ShellIconType.Large)
{
- var hIcon = ImageList_GetIcon(small ? smallImageListHandle : largeImageListHandle, index, IMAGELISTDRAWFLAGS.ILD_NORMAL);
- if (hIcon == IntPtr.Zero) return null;
- var icon = Icon.FromHandle(hIcon);
- var ret = (Icon)icon.Clone();
- DestroyIcon(hIcon);
- return ret;
+ const SHGFI baseFlags = SHGFI.SHGFI_USEFILEATTRIBUTES | SHGFI.SHGFI_ICON;
+ var shfi = new SHFILEINFO();
+ var ret = SHGetFileInfo(fileNameOrExtension, 0, ref shfi, shfiSz, baseFlags | (SHGFI)iconType);
+ if (ret == IntPtr.Zero)
+ ret = SHGetFileInfo(fileNameOrExtension, 0, ref shfi, shfiSz, SHGFI.SHGFI_ICON | (SHGFI)iconType);
+ return ret == IntPtr.Zero ? null : IconLocation.GetClonedIcon(shfi.hIcon);
}
}
}