From ca7ca983ca48afcae95515280f36e004ce262494 Mon Sep 17 00:00:00 2001 From: David Hall Date: Thu, 5 Apr 2018 13:25:38 -0600 Subject: [PATCH] Changed GetIcon to GetSystemIcon and added GetFileIcon. --- Windows.Shell/ShellImageList.cs | 63 +++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 22 deletions(-) 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); } } }