using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; namespace Silky.Interop { public class IconManager { public const int SHIL_LARGE = 0x0, SHIL_SMALL = 0x1, SHIL_EXTRALARGE = 0x2, SHIL_SYSSMALL = 0x3, SHIL_JUMBO = 0x4; const uint SHGFI_USEFILEATTRIBUTES = 0x000000010, SHGFI_SYSICONINDEX = 0x4000, ILD_TRANSPARENT = 1; private 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; }; private struct IMAGELISTDRAWPARAMS { public int cbmize; public IntPtr himl; public int i; public IntPtr hdcDst; public int x; public int y; public int cx; public int cy; public int xBitmap; public int yBitmap; public int rgbBk; public int rgbFg; public int fStyle; public int dwRop; public int fState; public int Frame; public int crEffect; } [StructLayout(LayoutKind.Sequential)] private struct IMAGEINFO { private readonly IntPtr hbmImage; private readonly IntPtr hbmMask; private readonly int Unused1; private readonly int Unused2; private readonly RECT rcImage; } [ComImport] [Guid("46EB5926-582E-4017-9FDF-E8998DAA0950")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IImageList { [PreserveSig] int Add( IntPtr hbmImage, IntPtr hbmMask, ref int pi ); [PreserveSig] int ReplaceIcon( int i, IntPtr hicon, ref int pi ); [PreserveSig] int SetOverlayImage( int iImage, int iOverlay ); [PreserveSig] int Replace( int i, IntPtr hbmImage, IntPtr hbmMask ); [PreserveSig] int AddMasked( IntPtr hbmImage, int crMask, ref int pi ); [PreserveSig] int Draw(ref IMAGELISTDRAWPARAMS pimldp); [PreserveSig] int Remove(int i); [PreserveSig] int GetIcon( int i, uint flags, ref IntPtr picon ); [PreserveSig] int GetImageInfo( int i, ref IMAGEINFO pImageInfo ); [PreserveSig] int Copy( int iDst, IImageList punkSrc, int iSrc, int uFlags ); [PreserveSig] int Merge( int i1, IImageList punk2, int i2, int dx, int dy, ref Guid riid, ref IntPtr ppv ); [PreserveSig] int Clone( ref Guid riid, ref IntPtr ppv ); [PreserveSig] int GetImageRect( int i, ref RECT prc ); [PreserveSig] int GetIconSize( ref int cx, ref int cy ); [PreserveSig] int SetIconSize( int cx, int cy ); [PreserveSig] int GetImageCount(ref int pi); [PreserveSig] int SetImageCount(int uNewCount); [PreserveSig] int SetBkColor( int clrBk, ref int pclr ); [PreserveSig] int GetBkColor(ref int pclr); [PreserveSig] int BeginDrag( int iTrack, int dxHotspot, int dyHotspot ); [PreserveSig] int EndDrag(); [PreserveSig] int DragEnter( IntPtr hwndLock, int x, int y ); [PreserveSig] int DragLeave(IntPtr hwndLock); [PreserveSig] int DragMove( int x, int y ); [PreserveSig] int SetDragCursorImage( ref IImageList punk, int iDrag, int dxHotspot, int dyHotspot ); [PreserveSig] int DragShowNolock(int fShow); [PreserveSig] int GetDragImage( ref POINT ppt, ref POINT pptHotspot, ref Guid riid, ref IntPtr ppv ); [PreserveSig] int GetItemFlags( int i, ref int dwFlags ); [PreserveSig] int GetOverlayImage( int iOverlay, ref int piIndex ); }; [DllImport("shell32.dll", EntryPoint = "#727")] static extern int SHGetImageList( int iImageList, ref Guid riid, out IImageList ppv ); [DllImport("shell32.dll", CharSet = CharSet.Auto)] static extern IntPtr SHGetFileInfo( string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags ); [DllImport("shell32.dll")] static extern int SHGetFileInfo( string pszPath, int dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags ); [DllImport("user32.dll")] static extern int DestroyIcon(IntPtr hIcon); [DllImport("gdi32.dll", SetLastError = true)] static extern bool DeleteObject(IntPtr hObject); [DllImport("user32.dll")] static extern bool GetIconInfo( IntPtr hIcon, out ICONINFO piconinfo ); public struct ICONINFO { public bool fIcon; public int xHotspot; public int yHotspot; public IntPtr hbmMask; public IntPtr hbmColor; } private static Bitmap ArgbBitmapFromHIcon(IntPtr hIcon) { ICONINFO ii = new ICONINFO(); GetIconInfo(hIcon, out ii); Bitmap bmp = Bitmap.FromHbitmap(ii.hbmColor); DeleteObject(ii.hbmColor); DeleteObject(ii.hbmMask); if (Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32) { return Bitmap.FromHicon(hIcon); } BitmapData bmData; Rectangle bmBounds = new Rectangle(0, 0, bmp.Width, bmp.Height); bmData = bmp.LockBits(bmBounds, ImageLockMode.ReadOnly, bmp.PixelFormat); Bitmap dstBitmap = new Bitmap(bmData.Width, bmData.Height, bmData.Stride, PixelFormat.Format32bppArgb, bmData.Scan0); bool IsAlphaBitmap = false; for (int y = 0; y <= bmData.Height - 1; y++) { for (int x = 0; x <= bmData.Width - 1; x++) { Color PixelColor = Color.FromArgb(Marshal.ReadInt32(bmData.Scan0, (bmData.Stride * y) + (4 * x))); if (PixelColor.A > 0 & PixelColor.A < 255) { IsAlphaBitmap = true; break; } } if (IsAlphaBitmap) { break; } } bmp.UnlockBits(bmData); if (IsAlphaBitmap == true) { return new Bitmap(dstBitmap); } else { return Bitmap.FromHicon(hIcon); } } public static Bitmap GetIcon(string FileName, int size) { var shfi = new SHFILEINFO(); var flags = SHGFI_SYSICONINDEX | SHGFI_USEFILEATTRIBUTES; var res = SHGetFileInfo(FileName, (int)FileAttributes.Normal, ref shfi, Marshal.SizeOf(shfi), flags); if (res == 0) { throw (new FileNotFoundException()); } var iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950"); IImageList iml; SHGetImageList(size, ref iidImageList, out iml); var hIcon = IntPtr.Zero; iml.GetIcon(shfi.iIcon, ILD_TRANSPARENT, ref hIcon); var bm = ArgbBitmapFromHIcon(hIcon); DestroyIcon(hIcon); return bm; } [StructLayout(LayoutKind.Sequential)] public struct RECT { private readonly int _Left; private readonly int _Top; private readonly int _Right; private readonly int _Bottom; } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; public POINT(int x, int y) { X = x; Y = y; } public static implicit operator Point(POINT p) { return new Point(p.X, p.Y); } public static implicit operator POINT(Point p) { return new POINT(p.X, p.Y); } } } }