using System; using System.Collections.Generic; using System.Linq; using Vanara.PInvoke; using static Vanara.PInvoke.ComCtl32; using static Vanara.PInvoke.Shell32; using static Vanara.PInvoke.User32; namespace Vanara.Windows.Shell { /// Used to determine the size of the icon returned by ShellImageList.GetSystemIcon. 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, /// /// These images are the size specified by GetSystemMetrics called with SM_CXSMICON and GetSystemMetrics called with SM_CYSMICON. /// SystemSmall = SHIL.SHIL_SYSSMALL, /// Windows Vista and later. The image is normally 256x256 pixels. Jumbo = SHIL.SHIL_JUMBO, } /* ***************************** * Developer Note: Keep these methods synchronized with identical methods in Vanara.Windows.Forms::Vanara.Extensions.IconExtension * ***************************** */ /// Represents the System Image List holding images for all shell icons. public static class ShellImageList { private static HIMAGELIST hSystemImageList; /// 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. /// /// A instance if found; otherwise . public static SafeHICON GetFileIcon(string fileNameOrExtension, ShellIconType iconType = ShellIconType.Large) { var shfi = new SHFILEINFO(); var ret = SHGetFileInfo(fileNameOrExtension, 0, ref shfi, SHFILEINFO.Size, SHGFI.SHGFI_USEFILEATTRIBUTES | SHGFI.SHGFI_ICON | (SHGFI)iconType); if (ret == IntPtr.Zero) ret = SHGetFileInfo(fileNameOrExtension, 0, ref shfi, SHFILEINFO.Size, SHGFI.SHGFI_ICON | (SHGFI)iconType); return ret == IntPtr.Zero ? null : new SafeHICON((IntPtr)shfi.hIcon); } /// Gets the system icon for the given file name or extension. /// The file name or extension. /// Size of the icon. /// A instance if found; otherwise . public static SafeHICON GetSystemIcon(string fileNameOrExtension, ShellImageSize iconSize = ShellImageSize.Large) { var shfi = new SHFILEINFO(); if (hSystemImageList.IsNull) hSystemImageList = SHGetFileInfo(fileNameOrExtension, 0, ref shfi, SHFILEINFO.Size, SHGFI.SHGFI_SYSICONINDEX | (iconSize == ShellImageSize.Small ? SHGFI.SHGFI_SMALLICON : 0)); if (hSystemImageList.IsNull) return null; if (iconSize <= ShellImageSize.Small) return ImageList_GetIcon(hSystemImageList, shfi.iIcon, IMAGELISTDRAWFLAGS.ILD_TRANSPARENT); return GetSystemIcon(shfi.iIcon, iconSize); } /// Gets the system icon for and index and size. /// The index of the system icon to retrieve. /// Size of the icon. /// An instance if found; otherwise . public static SafeHICON GetSystemIcon(int index, ShellImageSize iconSize = ShellImageSize.Large) => GetSystemIconHandle(index, iconSize); /// Gets the system icon for and index and size. /// The index of the system icon to retrieve. /// Size of the icon. /// An instance if found; otherwise . public static SafeHICON GetSystemIconHandle(int index, ShellImageSize iconSize = ShellImageSize.Large) { SHGetImageList((SHIL)iconSize, typeof(IImageList).GUID, out var il).ThrowIfFailed(); return ((IImageList)il).GetIcon(index, IMAGELISTDRAWFLAGS.ILD_TRANSPARENT); } /// Given a pixel size, return the ShellImageSize value with the closest size. /// Size, in pixels, of the image list size to search for. /// An image list size. public static ShellImageSize PixelsToSHIL(int pixels) => (ShellImageSize)ShellUtil.PixelsToSHIL(pixels); /// Given an image list size, return the related size, in pixels, of that size defined on the system. /// Size of the image list. /// Pixel size of corresponding system value. public static int SHILtoPixels(ShellImageSize imageListSize) => ShellUtil.SHILToPixels((SHIL)imageListSize); } }