using System;
using System.Collections.Generic;
using System.Text;
namespace WindowsFormsApplication1
{
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Reflection;
using System.Collections.Generic;
namespace BlackFox.Win32
{
public static class Icons
{
#region Custom exceptions class
public class IconNotFoundException : Exception
{
public IconNotFoundException(string fileName, int index)
: base(string.Format("Icon with Id = {0} wasn't found in file {1}", index, fileName))
{
}
}
public class UnableToExtractIconsException : Exception
{
public UnableToExtractIconsException(string fileName, int firstIconIndex, int iconCount)
: base(string.Format("Tryed to extract {2} icons starting from the one with id {1} from the \"{0}\" file but failed", fileName, firstIconIndex, iconCount))
{
}
}
#endregion
#region DllImports
///
/// Contains information about a file object.
/// struct SHFILEINFO
{
///
/// Handle to the icon that represents the file. You are responsible for
/// destroying this handle with DestroyIcon when you no longer need it.
/// public IntPtr hIcon;
///
/// Index of the icon image within the system image list.
/// public IntPtr iIcon;
///
/// Array of values that indicates the attributes of the file object.
/// For information about these values, see the IShellFolder::GetAttributesOf
/// method.
/// public uint dwAttributes;
///
/// String that contains the name of the file as it appears in the Microsoft
/// Windows Shell, or the path and file name of the file that contains the
/// icon representing the file.
/// [MarshalAs(UnmanagedType.ByValTStr, SizeCOnst= 260)]
public string szDisplayName;
///
/// String that describes the type of file.
/// [MarshalAs(UnmanagedType.ByValTStr, SizeCOnst= 80)]
public string szTypeName;
};
[Flags]
enum FileInfoFlags : int
{
///
/// Retrieve the handle to the icon that represents the file and the index
/// of the icon within the system image list. The handle is copied to the
/// hIcon member of the structure specified by psfi, and the index is copied
/// to the iIcon member.
/// SHGFI_ICON = 0x000000100,
///
/// Indicates that the function should not attempt to access the file
/// specified by pszPath. Rather, it should act as if the file specified by
/// pszPath exists with the file attributes passed in dwFileAttributes.
/// SHGFI_USEFILEATTRIBUTES = 0x000000010
}
///
/// Creates an array of handles to large or small icons extracted from
/// the specified executable file, dynamic-link library (DLL), or icon
/// file.
/// ///
/// Name of an executable file, DLL, or icon file from which icons will
/// be extracted.
///
///
///
/// Specifies the zero-based index of the first icon to extract. For
/// example, if this value is zero, the function extracts the first
/// icon in the specified file.
/// ///
/// If this value is �1 and and
/// are both NULL, the function returns
/// the total number of icons in the specified file. If the file is an
/// executable file or DLL, the return value is the number of
/// RT_GROUP_ICON resources. If the file is an .ico file, the return
/// value is 1.
/// ///
/// Windows 95/98/Me, Windows NT 4.0 and later: If this value is a
/// negative number and either or
/// is not NULL, the function begins by
/// extracting the icon whose resource identifier is equal to the
/// absolute value of . For example, use -3
/// to extract the icon whose resource identifier is 3.
/// ///
///
/// An array of icon handles that receives handles to the large icons
/// extracted from the file. If this parameter is NULL, no large icons
/// are extracted from the file.
///
///
/// An array of icon handles that receives handles to the small icons
/// extracted from the file. If this parameter is NULL, no small icons
/// are extracted from the file.
///
///
/// Specifies the number of icons to extract from the file.
///
///
/// If the parameter is -1, the
/// parameter is NULL, and the
/// parameter is NULL, then the return
/// value is the number of icons contained in the specified file.
/// Otherwise, the return value is the number of icons successfully
/// extracted from the file.
/// [DllImport("Shell32", CharSet = CharSet.Auto)]
extern static int ExtractIconEx(
[MarshalAs(UnmanagedType.LPTStr)]
string lpszFile,
int nIconIndex,
IntPtr[] phIconLarge,
IntPtr[] phIconSmall,
int nIcons);
[DllImport("Shell32", CharSet = CharSet.Auto)]
extern static IntPtr SHGetFileInfo(
string pszPath,
int dwFileAttributes,
out SHFILEINFO psfi,
int cbFileInfo,
FileInfoFlags uFlags);
#endregion
///
/// Two constants extracted from the FileInfoFlags, the only that are
/// meaningfull for the user of this class.
/// public enum SystemIconSize : int
{
Large = 0x000000000,
Small = 0x000000001
}
///
/// Get the number of icons in the specified file.
/// ///
Full path of the file to look for.
///
static int GetIconsCountInFile(string fileName)
{
return ExtractIconEx(fileName, -1, null, null, 0);
}
#region ExtractIcon-like functions
public static void ExtractEx(string fileName, List
largeIcons,
List smallIcons, int firstIconIndex, int iconCount)
{
/*
* Memory allocations
*/
IntPtr[] smallIcOnsPtrs= null;
IntPtr[] largeIcOnsPtrs= null;
if (smallIcons != null)
{
smallIcOnsPtrs= new IntPtr[iconCount];
}
if (largeIcons != null)
{
largeIcOnsPtrs= new IntPtr[iconCount];
}
/*
* Call to native Win32 API
*/
int apiResult = ExtractIconEx(fileName, firstIconIndex, largeIconsPtrs, smallIconsPtrs, iconCount);
if (apiResult != iconCount)
{
throw new UnableToExtractIconsException(fileName, firstIconIndex, iconCount);
}
/*
* Fill lists
*/
if (smallIcons != null)
{
smallIcons.Clear();
foreach (IntPtr actualIconPtr in smallIconsPtrs)
{
smallIcons.Add(Icon.FromHandle(actualIconPtr));
}
}
if (largeIcons != null)
{
largeIcons.Clear();
foreach (IntPtr actualIconPtr in largeIconsPtrs)
{
largeIcons.Add(Icon.FromHandle(actualIconPtr));
}
}
}
public static List ExtractEx(string fileName, SystemIconSize size,
int firstIconIndex, int iconCount)
{
List icOnList= new List();
switch (size)
{
case SystemIconSize.Large:
ExtractEx(fileName, iconList, null, firstIconIndex, iconCount);
break;
case SystemIconSize.Small:
ExtractEx(fileName, null, iconList, firstIconIndex, iconCount);
break;
default:
throw new ArgumentOutOfRangeException("size");
}
return iconList;
}
public static void Extract(string fileName, List largeIcons, List smallIcons)
{
int icOnCount= GetIconsCountInFile(fileName);
ExtractEx(fileName, largeIcons, smallIcons, 0, iconCount);
}
public static List Extract(string fileName, SystemIconSize size)
{
int icOnCount= GetIconsCountInFile(fileName);
return ExtractEx(fileName, size, 0, iconCount);
}
public static Icon ExtractOne(string fileName, int index, SystemIconSize size)
{
try
{
List icOnList= ExtractEx(fileName, size, index, 1);
return iconList[0];
}
catch (UnableToExtractIconsException)
{
throw new IconNotFoundException(fileName, index);
}
}
public static void ExtractOne(string fileName, int index,
out Icon largeIcon, out Icon smallIcon)
{
List smallIcOnList= new List();
List largeIcOnList= new List();
try
{
ExtractEx(fileName, largeIconList, smallIconList, index, 1);
largeIcon = largeIconList[0];
smallIcon = smallIconList[0];
}
catch (UnableToExtractIconsException)
{
throw new IconNotFoundException(fileName, index);
}
}
#endregion
//this will look throw the registry
//to find if the Extension have an icon.
public static Icon IconFromExtension(string extension,
SystemIconSize size)
{
// Add the '.' to the extension if needed
if (extension[0] != '.') extension = '.' + extension;
//opens the registry for the wanted key.
RegistryKey Root = Registry.ClassesRoot;
RegistryKey ExtensiOnKey= Root.OpenSubKey(extension);
ExtensionKey.GetValueNames();
RegistryKey ApplicatiOnKey=
Root.OpenSubKey(ExtensionKey.GetValue("").ToString());
//gets the name of the file that have the icon.
string IcOnLocation=
ApplicationKey.OpenSubKey("DefaultIcon").GetValue("").ToString();
string[] IcOnPath= IconLocation.Split(',');
if (IconPath[1] == null) IconPath[1] = "0";
IntPtr[] Large = new IntPtr[1], Small = new IntPtr[1];
//extracts the icon from the file.
ExtractIconEx(IconPath[0],
Convert.ToInt16(IconPath[1]), Large, Small, 1);
return size == SystemIconSize.Large ?
Icon.FromHandle(Large[0]) : Icon.FromHandle(Small[0]);
}
public static Icon IconFromExtensionShell(string extension, SystemIconSize size)
{
//add '.' if nessesry
if (extension[0] != '.') extension = '.' + extension;
//temp struct for getting file shell info
SHFILEINFO fileInfo = new SHFILEINFO();
SHGetFileInfo(
extension,
,
out fileInfo,
Marshal.SizeOf(fileInfo),
FileInfoFlags.SHGFI_ICON | FileInfoFlags.SHGFI_USEFILEATTRIBUTES | (FileInfoFlags)size);
return Icon.FromHandle(fileInfo.hIcon);
}
public static Icon IconFromResource(string resourceName)
{
Assembly assembly = Assembly.GetCallingAssembly();
return new Icon(assembly.GetManifestResourceStream(resourceName));
}
///
/// Parse strings in registry who contains the name of the icon and
/// the index of the icon an return both parts.
///
/// The full string in the form "path,index" as found in registry.
/// The "path" part of the string.
/// The "index" part of the string.
public static void ExtractInformationsFromRegistryString(
string regString, out string fileName, out int index)
{
if (regString == null)
{
throw new ArgumentNullException("regString");
}
if (regString.Length == 0)
{
throw new ArgumentException("The string should not be empty.", "regString");
}
index = 0;
string[] strArr = regString.Replace("\"", "").Split(',');
fileName = strArr[0].Trim();
if (strArr.Length > 1)
{
int.TryParse(strArr[1].Trim(), out index);
}
}
public static Icon ExtractFromRegistryString(string regString, SystemIconSize size)
{
string fileName;
int index;
ExtractInformationsFromRegistryString(regString, out fileName, out index);
return ExtractOne(fileName, index, size);
}
}
}
}