diff --git a/Windows.Shell/ShellImageList.cs b/Windows.Shell/ShellImageList.cs index c9045de3..26fcc99e 100644 --- a/Windows.Shell/ShellImageList.cs +++ b/Windows.Shell/ShellImageList.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Drawing; +using System.Linq; using Vanara.PInvoke; using static Vanara.PInvoke.ComCtl32; using static Vanara.PInvoke.Shell32; @@ -24,8 +26,13 @@ namespace Vanara.Windows.Shell /// 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 + Jumbo = SHIL.SHIL_JUMBO, } /* ***************************** @@ -34,8 +41,23 @@ namespace Vanara.Windows.Shell /// Represents the System Image List holding images for all shell icons. public static class ShellImageList { + private const string REGSTR_PATH_METRICS = "Control Panel\\Desktop\\WindowMetrics"; + private static readonly Dictionary g_rgshil; + private static readonly int SHIL_COUNT; private static HIMAGELIST hSystemImageList; + static ShellImageList() + { + SHIL_COUNT = Enum.GetValues(typeof(ShellImageSize)).Length; + g_rgshil = new Dictionary(SHIL_COUNT); // new ushort[SHIL_COUNT]; + var sysCxIco = GetSystemMetrics(SystemMetric.SM_CXICON); + g_rgshil[ShellImageSize.Large] = (ushort)(int)Microsoft.Win32.Registry.CurrentUser.GetValue($"{REGSTR_PATH_METRICS}\\Shell Icon Size", sysCxIco); + g_rgshil[ShellImageSize.Small] = (ushort)(int)Microsoft.Win32.Registry.CurrentUser.GetValue($"{REGSTR_PATH_METRICS}\\Shell Small Icon Size", sysCxIco / 2); + g_rgshil[ShellImageSize.ExtraLarge] = (ushort)(3 * sysCxIco / 2); + g_rgshil[ShellImageSize.SystemSmall] = (ushort)GetSystemMetrics(SystemMetric.SM_CXSMICON); + g_rgshil[ShellImageSize.Jumbo] = 256; + } + /// Gets the Shell icon for the given file name or extension. /// The file name or extension . /// @@ -71,10 +93,26 @@ namespace Vanara.Windows.Shell /// The index of the system icon to retrieve. /// Size of the icon. /// An instance if found; otherwise . - public static Icon GetSystemIcon(int index, ShellImageSize iconSize = ShellImageSize.Large) + public static Icon GetSystemIcon(int index, ShellImageSize iconSize = ShellImageSize.Large) => GetSystemIconHandle(index, iconSize)?.ToIcon(); + + /// 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 il.GetIcon(index, IMAGELISTDRAWFLAGS.ILD_TRANSPARENT)?.ToIcon(); + return 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) => g_rgshil.Aggregate((x, y) => Math.Abs(x.Value - pixels) < Math.Abs(y.Value - pixels) ? x : y).Key; + + /// 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) => g_rgshil[imageListSize]; } } \ No newline at end of file