namespace VideoBrowser.Controls.CefSharpBrowser.Helpers { using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; /// /// Internals are mostly from here: http://www.codeproject.com/Articles/2532/Obtaining-and-managing-file-and-folder-icons-using /// Caches all results. /// public static class ApplicationIconHelper { #region Fields private static readonly Dictionary _largeIconCache = new Dictionary(); private static readonly Dictionary _smallIconCache = new Dictionary(); #endregion Fields #region Methods /// /// Get an icon for a given filename. /// /// any filename. /// 16x16 or 32x32 icon. /// null if path is null, otherwise - an icon. public static ImageSource FindIconForFilename(this string fileName, bool large) { var extension = Path.GetExtension(fileName); if (extension == null) { return null; } var cache = large ? _largeIconCache : _smallIconCache; ImageSource icon; if (cache.TryGetValue(extension, out icon)) { return icon; } icon = IconReader.GetFileIcon(fileName, large ? IconReader.IconSize.Large : IconReader.IconSize.Small, false).ToImageSource(); cache.Add(extension, icon); return icon; } /// /// http://stackoverflow.com/a/6580799/1943849. /// /// The icon. /// The . private static ImageSource ToImageSource(this Icon icon) { var imageSource = Imaging.CreateBitmapSourceFromHIcon( icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); return imageSource; } #endregion Methods /// /// Provides static methods to read system icons for both folders and files. /// private static class IconReader { #region Enums /// /// Options to specify the size of icons to return. /// public enum IconSize { /// /// Specify large icon - 32 pixels by 32 pixels. /// Large = 0, /// /// Specify small icon - 16 pixels by 16 pixels. /// Small = 1 } #endregion Enums #region Methods /// /// Returns an icon for a given file - indicated by the name parameter. /// /// Pathname for file. /// Large or small. /// Whether to include the link icon. /// System.Drawing.Icon. public static Icon GetFileIcon(string name, IconSize size, bool linkOverlay) { var shfi = new Shell32.Shfileinfo(); var flags = Shell32.ShgfiIcon | Shell32.ShgfiUsefileattributes; if (linkOverlay) { flags += Shell32.ShgfiLinkoverlay; } /* Check the size specified for return. */ if (IconSize.Small == size) { flags += Shell32.ShgfiSmallicon; } else { flags += Shell32.ShgfiLargeicon; } Shell32.SHGetFileInfo(name, Shell32.FileAttributeNormal, ref shfi, (uint)Marshal.SizeOf(shfi), flags); // Copy (clone) the returned icon to a new object, thus allowing us to clean-up properly var icon = (Icon)Icon.FromHandle(shfi.hIcon).Clone(); User32.DestroyIcon(shfi.hIcon); // Cleanup return icon; } #endregion Methods } /// /// Wraps necessary Shell32.dll structures and functions required to retrieve Icon Handles using SHGetFileInfo. Code /// courtesy of MSDN Cold Rooster Consulting case study. /// private static class Shell32 { #region Constants public const uint FileAttributeNormal = 0x00000080; public const uint ShgfiIcon = 0x000000100;// get icon public const uint ShgfiLargeicon = 0x000000000;// get large icon public const uint ShgfiLinkoverlay = 0x000008000;// put a link overlay on icon public const uint ShgfiSmallicon = 0x000000001;// get small icon public const uint ShgfiUsefileattributes = 0x000000010;// use passed dwFileAttribute private const int MaxPath = 256; #endregion Constants #region Methods /// /// The SHGetFileInfo. /// /// The pszPath. /// The dwFileAttributes. /// The psfi. /// The cbFileInfo. /// The uFlags. /// The . [DllImport("Shell32.dll")] public static extern IntPtr SHGetFileInfo( string pszPath, uint dwFileAttributes, ref Shfileinfo psfi, uint cbFileInfo, uint uFlags ); #endregion Methods /// /// Defines the . /// [StructLayout(LayoutKind.Sequential)] public struct Shfileinfo { #region Constants private const int Namesize = 80; #endregion Constants #region Fields public readonly IntPtr hIcon; private readonly uint dwAttributes; private readonly int iIcon; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxPath)] private readonly string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Namesize)] private readonly string szTypeName; #endregion Fields } ; } /// /// Wraps necessary functions imported from User32.dll. Code courtesy of MSDN Cold Rooster Consulting example. /// private static class User32 { #region Methods /// /// Provides access to function required to delete handle. This method is used internally /// and is not required to be called separately. /// /// Pointer to icon handle. /// N/A. [DllImport("User32.dll")] public static extern int DestroyIcon(IntPtr hIcon); #endregion Methods } } }