mirror of https://github.com/dahall/Vanara.git
126 lines
4.3 KiB
C#
126 lines
4.3 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using Vanara.PInvoke;
|
|
using static Vanara.PInvoke.Shell32;
|
|
using static Vanara.PInvoke.User32;
|
|
|
|
namespace Vanara.Windows.Shell
|
|
{
|
|
/// <summary>Represents a standard system icon.</summary>
|
|
public class StockIcon : IDisposable
|
|
{
|
|
private SHGSI curFlags;
|
|
private SHSTOCKICONID curId;
|
|
private HICON hIcon;
|
|
private IconLocation location;
|
|
private int systemImageIndex;
|
|
|
|
static StockIcon() => FileIconInit(false);
|
|
|
|
/// <summary>Creates a new StockIcon instance with the specified identifer and options.</summary>
|
|
/// <param name="id">A value that identifies the icon represented by this instance.</param>
|
|
/// <param name="size">A value that indicates the size of the stock icon.</param>
|
|
/// <param name="isLinkOverlay">A bool value that indicates whether the icon has a link overlay.</param>
|
|
/// <param name="isSelected">A bool value that indicates whether the icon is in a selected state.</param>
|
|
public StockIcon(SHSTOCKICONID id, ShellIconType size = ShellIconType.Large, bool isLinkOverlay = false, bool isSelected = false)
|
|
{
|
|
Identifier = id;
|
|
LinkOverlay = isLinkOverlay;
|
|
Selected = isSelected;
|
|
Size = size;
|
|
}
|
|
|
|
/// <summary>Finalizes an instance of the <see cref="StockIcon"/> class.</summary>
|
|
~StockIcon()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
/// <summary>Gets the icon image in <see cref="System.Drawing.Bitmap"/> format.</summary>
|
|
public Bitmap Bitmap { get { Refresh(); return hIcon.IsNull ? null : Bitmap.FromHicon((IntPtr)hIcon); } }
|
|
|
|
/// <summary>Gets the icon image in <see cref="System.Drawing.Icon"/> format.</summary>
|
|
public Icon Icon { get { Refresh(); return hIcon.IsNull ? null : Icon.FromHandle((IntPtr)hIcon); } }
|
|
|
|
/// <summary>Gets the icon handle.</summary>
|
|
/// <value>The icon handle.</value>
|
|
public HICON IconHandle => hIcon;
|
|
|
|
/// <summary>Gets or sets the Stock Icon identifier associated with this icon.</summary>
|
|
public SHSTOCKICONID Identifier { get; set; }
|
|
|
|
/// <summary>Gets or sets a value that cotrols whether to put a link overlay on the icon.</summary>
|
|
/// <value>A <see cref="bool"/> value.</value>
|
|
public bool LinkOverlay { get; set; }
|
|
|
|
/// <summary>Gets the icon location, composed of a resource path and the icon's index.</summary>
|
|
/// <value>The icon location.</value>
|
|
public IconLocation Location { get { Refresh(); return location; } }
|
|
|
|
/// <summary>Gets or sets a value indicating whether the icon appears selected.</summary>
|
|
/// <value>A <see cref="bool"/> value.</value>
|
|
public bool Selected { get; set; }
|
|
|
|
/// <summary>Gets or sets a value that controls the size of the Stock Icon.</summary>
|
|
/// <value>A <see cref="ShellIconType"/> value.</value>
|
|
public ShellIconType Size { get; set; }
|
|
|
|
/// <summary>Gets the index of the image in the system icon cache.</summary>
|
|
/// <value>The index of the system image.</value>
|
|
public int SystemImageIndex { get { Refresh(); return systemImageIndex; } }
|
|
|
|
/// <summary>Release the native objects</summary>
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
System.GC.SuppressFinalize(this);
|
|
}
|
|
|
|
/// <summary>Release the native and managed objects</summary>
|
|
/// <param name="disposing">Indicates that this is being called from Dispose(), rather than the finalizer.</param>
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
// dispose managed resources here
|
|
}
|
|
|
|
// Unmanaged resources
|
|
if (hIcon != IntPtr.Zero)
|
|
DestroyIcon(hIcon);
|
|
}
|
|
|
|
private SHGSI GetFlags() => SHGSI.SHGSI_ICON | SHGSI.SHGSI_ICONLOCATION | SHGSI.SHGSI_SYSICONINDEX | (SHGSI)Size | (Selected ? SHGSI.SHGSI_SELECTED : 0) | (LinkOverlay ? SHGSI.SHGSI_LINKOVERLAY : 0);
|
|
|
|
private void Refresh()
|
|
{
|
|
var flags = GetFlags();
|
|
if (curFlags == flags && curId == Identifier)
|
|
return;
|
|
|
|
if (hIcon != IntPtr.Zero)
|
|
{
|
|
DestroyIcon(hIcon);
|
|
hIcon = default;
|
|
}
|
|
|
|
var info = SHSTOCKICONINFO.Default;
|
|
var hr = SHGetStockIconInfo(curId = Identifier, curFlags = flags, ref info);
|
|
|
|
// If we get an error, return null as the icon requested might not be supported on the current system
|
|
if (hr == HRESULT.E_INVALIDARG)
|
|
throw new InvalidOperationException("Invalid identifier.");
|
|
else if (hr.Succeeded)
|
|
{
|
|
hIcon = info.hIcon;
|
|
location = new IconLocation(info.szPath, info.iIcon);
|
|
systemImageIndex = info.iSysImageIndex;
|
|
}
|
|
else
|
|
{
|
|
location = null;
|
|
systemImageIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
} |