Skip to content

Instantly share code, notes, and snippets.

@JohanLarsson
Created January 3, 2014 15:32
Show Gist options
  • Save JohanLarsson/8239781 to your computer and use it in GitHub Desktop.
Save JohanLarsson/8239781 to your computer and use it in GitHub Desktop.
public static class IconsRepository
{
private static readonly Dictionary<string, Icon> CachedIcons = new Dictionary<string, Icon>();
private static readonly Dictionary<string, BitmapImage> CachedBitmapImages = new Dictionary<string, BitmapImage>();
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint uFlags);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DestroyIcon(IntPtr hIcon);
public const uint SHGFI_ICON = 0x000000100;
public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
public const uint SHGFI_OPENICON = 0x000000002;
public const uint SHGFI_SMALLICON = 0x000000001;
public const uint SHGFI_LARGEICON = 0x000000000;
public const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
private static Icon _smallOpenFolderIcon;
public static Icon SmallOpenFolderIcon
{
get
{
return _smallOpenFolderIcon ??
(_smallOpenFolderIcon = GetFolderIcon(IconSize.Small, FolderType.Open));
}
}
private static Icon _smallClosedFolderIcon;
public static Icon SmallClosedFolderIcon
{
get
{
return _smallClosedFolderIcon ??
(_smallClosedFolderIcon = GetFolderIcon(IconSize.Small, FolderType.Closed));
}
}
private static BitmapImage _smallClosedFolderBitmapImage;
public static BitmapImage SmallClosedFolderBitmapImage
{
get
{
return _smallClosedFolderBitmapImage ??
(_smallClosedFolderBitmapImage = SmallClosedFolderIcon.ToBitmapImage());
}
}
private static BitmapImage _smallOpenFolderBitmapImage;
public static BitmapImage SmallOpenFolderBitmapImage
{
get
{
return _smallOpenFolderBitmapImage ??
(_smallOpenFolderBitmapImage = SmallOpenFolderIcon.ToBitmapImage());
}
}
/// <summary>
/// http://stackoverflow.com/a/1601670/1069200
/// </summary>
/// <param name="size"></param>
/// <param name="folderType"></param>
/// <returns></returns>
public static Icon GetFolderIcon(IconSize size, FolderType folderType)
{
// Need to add size check, although errors generated at present!
uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
if (FolderType.Open == folderType)
{
flags += SHGFI_OPENICON;
}
if (IconSize.Small == size)
{
flags += SHGFI_SMALLICON;
}
else
{
flags += SHGFI_LARGEICON;
}
// Get the folder icon
var shfi = new SHFILEINFO();
var res = SHGetFileInfo(@"C:\Windows",
FILE_ATTRIBUTE_DIRECTORY,
out shfi,
(uint)Marshal.SizeOf(shfi),
flags);
if (res == IntPtr.Zero)
throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
// Load the icon from an HICON handle
Icon.FromHandle(shfi.hIcon);
// Now clone the icon, so that it can be successfully stored in an ImageList
var icon = (Icon)Icon.FromHandle(shfi.hIcon).Clone();
DestroyIcon(shfi.hIcon); // Cleanup
return icon;
}
public static Icon GetFileIcon(string filename)
{
string extension = Path.GetExtension(filename);
if (CachedIcons.ContainsKey(extension))
return CachedIcons[extension];
Icon icon = Icon.ExtractAssociatedIcon(filename);
CachedIcons.Add(extension,icon);
CachedBitmapImages.Add(extension,icon.ToBitmapImage());
return icon;
}
public static BitmapImage GetFileBitmapImage(string filename)
{
string extension = Path.GetExtension(filename);
if (CachedBitmapImages.ContainsKey(extension))
return CachedBitmapImages[extension];
GetFileIcon(filename);
return CachedBitmapImages[extension];
}
public static BitmapImage ToBitmapImage(this Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
bitmap.Save(memory, ImageFormat.Png);
memory.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
return bitmapImage;
}
}
public static BitmapImage ToBitmapImage(this Icon icon)
{
using (MemoryStream memory = new MemoryStream())
{
icon.Save(memory);
memory.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
return bitmapImage;
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
public enum FolderType
{
Closed,
Open
}
public enum IconSize
{
Large,
Small
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment