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);
}
}