
Introduction
IconHandler is a class for getting icons from files and the default associated icons by the extension of the file.
Background
It was originally writtin for a P2P project that never got out, called Kibutz. I decided to add the shell and resource functions becouse of a comment I got here. The const value has also been fixed (check IconSize
).
Using the code
The class includes four simple-to-use functions:
IconFromFile(Filename,IconSize,Index)
This will get a single icon from a file with the specific index. If no icon was found or if the index was outside of the bounds, null
will be returned.
IconsFromFile(Filename,IconSize)
This will return an Icon
typed array of icons.
IconFromExtension(Extension,IconSize)
This will return an icon associated with an extension -- if it exists -- by using Shell API; if not null
will be returned.
IconFromResource(string ResourceName)
This will return an icon from the assembly resource if it exists.
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Reflection;
using System.IO;
namespace IconHandler
{
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 IconSize : uint
{
Large = 0x0,
Small = 0x1
}
public class IconHandler
{
const uint SHGFI_ICON = 0x100;
const uint SHGFI_USEFILEATTRIBUTES = 0x10;
[DllImport("Shell32", CharSet=CharSet.Auto)]
internal extern static int ExtractIconEx (
[MarshalAs(UnmanagedType.LPTStr)]
string lpszFile,
int nIconIndex,
IntPtr[] phIconLarge,
IntPtr[] phIconSmall,
int nIcons);
[DllImport("shell32.dll")]
static extern IntPtr SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbSizeFileInfo,
uint uFlags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);
public static Icon[] IconsFromFile(string Filename,IconSize Size)
{
int IconCount = ExtractIconEx(Filename,-1,null,null,0);
IntPtr[] IconPtr = new IntPtr[IconCount];
Icon TempIcon;
if (Size == IconSize.Small)
ExtractIconEx(Filename,0,null,IconPtr,IconCount);
else
ExtractIconEx(Filename,0,IconPtr,null,IconCount);
Icon[] IconList = new Icon[IconCount];
for (int i = 0; i < IconCount; i++)
{
TempIcon = (Icon) Icon.FromHandle(IconPtr[i]);
IconList[i] = GetManagedIcon(ref TempIcon);
}
return IconList;
}
public static Icon IconFromFile(
string Filename,IconSize Size,int Index)
{
int IconCount = ExtractIconEx(Filename,-1,null,null,0);
if (IconCount <= 0 || Index >= IconCount) return null;
Icon TempIcon;
IntPtr[] IconPtr = new IntPtr[1];
if (Size == IconSize.Small)
ExtractIconEx(Filename,Index,null,IconPtr,1);
else
ExtractIconEx(Filename,Index,IconPtr,null,1);
TempIcon = Icon.FromHandle(IconPtr[0]);
return GetManagedIcon(ref TempIcon);
}
public static Icon IconFromExtension(string Extension,IconSize Size)
{
try
{
Icon TempIcon;
if (Extension[0] != '.') Extension = '.' + Extension;
SHFILEINFO TempFileInfo = new SHFILEINFO();
SHGetFileInfo(
Extension,
0,
ref TempFileInfo,
(uint)Marshal.SizeOf(TempFileInfo),
SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | (uint) Size);
TempIcon = (Icon) Icon.FromHandle(TempFileInfo.hIcon);
return GetManagedIcon(ref TempIcon);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(
"error while trying to get icon for " + Extension +
" :" + e.Message);
return null;
}
}
public static Icon IconFromResource(string ResourceName)
{
Assembly TempAssembly = Assembly.GetCallingAssembly();
return new Icon(TempAssembly.GetManifestResourceStream(
ResourceName));
}
public static void SaveIconFromImage(
Image SourceImage,string IconFilename,IconSize DestenationIconSize)
{
Size NewIconSize = DestenationIconSize ==
IconSize.Large ? new Size(32,32) : new Size(16,16);
Bitmap RawImage = new Bitmap(SourceImage,NewIconSize);
Icon TempIcon = Icon.FromHandle(RawImage.GetHicon());
FileStream NewIconStream = new FileStream(
IconFilename,FileMode.Create);
TempIcon.Save(NewIconStream);
NewIconStream.Close();
}
public static void SaveIcon(Icon SourceIcon,string IconFilename)
{
FileStream NewIconStream = new FileStream(
IconFilename,FileMode.Create);
SourceIcon.Save(NewIconStream);
NewIconStream.Close();
}
public static Icon GetManagedIcon(ref Icon UnmanagedIcon)
{
Icon ManagedIcon = (Icon) UnmanagedIcon.Clone();
DestroyIcon(UnmanagedIcon.Handle);
return ManagedIcon;
}
}
}
Points of interest
What got me to write this was that I didn't find anything like this around. It's not complicated code, but when you want to use icons you don't plan on wasting your time dealing with it a lot. So, it's comfortable to have this little piece of code around.
History
- 12 January, 2005 - Original version posted
- 1 February, 2006 - First update
- 23 May, 2007 - Second update