using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; //using System.Windows; using System.Drawing.Imaging; //using System.Windows.Media.Imaging; using System.Diagnostics; using System.Drawing; using System.Windows; namespace HeliosPlus { class IconFromFile { // Constants that we need in the function call private const int SHGFI_ICON = 0x100; private const int SHGFI_SMALLICON = 0x1; private const int SHGFI_LARGEICON = 0x0; private const int SHIL_JUMBO = 0x4; private const int SHIL_EXTRALARGE = 0x2; // This structure will contain information about the file public struct SHFILEINFO { // Handle to the icon representing the file public IntPtr hIcon; // Index of the icon within the image list public int iIcon; // Various attributes of the file public uint dwAttributes; // Path to the file [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string szDisplayName; // File type [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; [System.Runtime.InteropServices.DllImport("Kernel32.dll")] public static extern Boolean CloseHandle(IntPtr handle); private struct IMAGELISTDRAWPARAMS { public int cbSize; public IntPtr himl; public int i; public IntPtr hdcDst; public int x; public int y; public int cx; public int cy; public int xBitmap; // x offest from the upperleft of bitmap public int yBitmap; // y offset from the upperleft of bitmap 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 { public IntPtr hbmImage; public IntPtr hbmMask; public int Unused1; public int Unused2; public Rect rcImage; } #region Private ImageList COM Interop (XP) [ComImportAttribute()] [GuidAttribute("46EB5926-582E-4017-9FDF-E8998DAA0950")] [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] //helpstring("Image List"), 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, int 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); }; #endregion /// /// SHGetImageList is not exported correctly in XP. See KB316931 /// http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q316931 /// Apparently (and hopefully) ordinal 727 isn't going to change. /// [DllImport("shell32.dll", EntryPoint = "#727")] private extern static int SHGetImageList( int iImageList, ref Guid riid, out IImageList ppv ); // The signature of SHGetFileInfo (located in Shell32.dll) [DllImport("Shell32.dll")] public static extern int SHGetFileInfo(string pszPath, int dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags); [DllImport("Shell32.dll")] public static extern int SHGetFileInfo(IntPtr pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags); [DllImport("shell32.dll", SetLastError = true)] static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, Int32 nFolder, ref IntPtr ppidl); [DllImport("user32")] public static extern int DestroyIcon(IntPtr hIcon); public struct pair { public System.Drawing.Icon icon { get; set; } public IntPtr iconHandleToDestroy { set; get; } } public static int DestroyIcon2(IntPtr hIcon) { return DestroyIcon(hIcon); } /*private static BitmapSource bitmap_source_of_icon(System.Drawing.Icon ic) { var ic2 = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(ic.Handle, System.Windows.Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); ic2.Freeze(); return ((BitmapSource)ic2); }*/ /*public static BitmapSource SystemIcon(bool small, ShellLib.ShellApi.CSIDL csidl) { IntPtr pidlTrash = IntPtr.Zero; int hr = SHGetSpecialFolderLocation(IntPtr.Zero, (int)csidl, ref pidlTrash); Debug.Assert(hr == 0); SHFILEINFO shinfo = new SHFILEINFO(); uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // Get a handle to the large icon uint flags; uint SHGFI_PIDL = 0x000000008; if (!small) { flags = SHGFI_PIDL | SHGFI_ICON | SHGFI_LARGEICON | SHGFI_USEFILEATTRIBUTES; } else { flags = SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES; } var res = SHGetFileInfo(pidlTrash, 0, ref shinfo, Marshal.SizeOf(shinfo), flags); Debug.Assert(res != 0); var myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon); Marshal.FreeCoTaskMem(pidlTrash); var bs = bitmap_source_of_icon(myIcon); myIcon.Dispose(); bs.Freeze(); // importantissimo se no fa memory leak DestroyIcon(shinfo.hIcon); CloseHandle(shinfo.hIcon); return bs; }*/ /* public static BitmapSource GetSmallBitmapFromFile(string FileName, bool small, bool checkDisk, bool addOverlay) { SHFILEINFO shinfo = new SHFILEINFO(); uint SHGFI_USEFILEATTRIBUTES = 0x000000010; uint SHGFI_LINKOVERLAY = 0x000008000; uint flags; if (small) { flags = SHGFI_ICON | SHGFI_SMALLICON; } else { flags = SHGFI_ICON | SHGFI_LARGEICON; } if (!checkDisk) flags |= SHGFI_USEFILEATTRIBUTES; if (addOverlay) flags |= SHGFI_LINKOVERLAY; var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags); if (res == 0) { throw (new System.IO.FileNotFoundException()); } var myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon); var bs = bitmap_source_of_icon(myIcon); myIcon.Dispose(); bs.Freeze(); // importantissimo se no fa memory leak DestroyIcon(shinfo.hIcon); CloseHandle(shinfo.hIcon); return bs; }*/ public static Bitmap GetSmallBitmapFromFile(string FileName, bool small, bool checkDisk, bool addOverlay) { SHFILEINFO shinfo = new SHFILEINFO(); uint SHGFI_USEFILEATTRIBUTES = 0x000000010; uint SHGFI_LINKOVERLAY = 0x000008000; uint flags; if (small) { flags = SHGFI_ICON | SHGFI_SMALLICON; } else { flags = SHGFI_ICON | SHGFI_LARGEICON; } if (!checkDisk) flags |= SHGFI_USEFILEATTRIBUTES; if (addOverlay) flags |= SHGFI_LINKOVERLAY; var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags); if (res == 0) { throw (new System.IO.FileNotFoundException()); } var myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon); Bitmap bm = myIcon.ToBitmap(); myIcon.Dispose(); DestroyIcon(shinfo.hIcon); //CloseHandle(shinfo.hIcon); return bm; } /*public static BitmapSource GetLargeBitmapSourceFromFile(string FileName, bool jumbo, bool checkDisk) { SHFILEINFO shinfo = new SHFILEINFO(); uint SHGFI_USEFILEATTRIBUTES = 0x000000010; uint SHGFI_SYSICONINDEX = 0x4000; int FILE_ATTRIBUTE_NORMAL = 0x80; uint flags; flags = SHGFI_SYSICONINDEX; if (!checkDisk) // This does not seem to work. If I try it, a folder icon is always returned. flags |= SHGFI_USEFILEATTRIBUTES; var res = SHGetFileInfo(FileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, Marshal.SizeOf(shinfo), flags); if (res == 0) { throw (new System.IO.FileNotFoundException()); } var iconIndex = shinfo.iIcon; // Get the System IImageList object from the Shell: Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950"); IImageList iml; int size = jumbo ? SHIL_JUMBO : SHIL_EXTRALARGE; var hres = SHGetImageList(size, ref iidImageList, out iml); // writes iml //if (hres == 0) //{ // throw (new System.Exception("Error SHGetImageList")); //} IntPtr hIcon = IntPtr.Zero; int ILD_TRANSPARENT = 1; hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon); //if (hres == 0) //{ // throw (new System.Exception("Error iml.GetIcon")); //} var myIcon = System.Drawing.Icon.FromHandle(hIcon); var bs = bitmap_source_of_icon(myIcon); myIcon.Dispose(); bs.Freeze(); // very important to avoid memory leak DestroyIcon(hIcon); CloseHandle(hIcon); return bs; }*/ public static Icon GetSmallIconFromFile(string FileName, bool small, bool checkDisk, bool addOverlay) { SHFILEINFO shinfo = new SHFILEINFO(); uint SHGFI_USEFILEATTRIBUTES = 0x000000010; uint SHGFI_LINKOVERLAY = 0x000008000; uint flags; if (small) { flags = SHGFI_ICON | SHGFI_SMALLICON; } else { flags = SHGFI_ICON | SHGFI_LARGEICON; } if (!checkDisk) flags |= SHGFI_USEFILEATTRIBUTES; if (addOverlay) flags |= SHGFI_LINKOVERLAY; var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags); if (res == 0) { throw (new System.IO.FileNotFoundException()); } var myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon); DestroyIcon(shinfo.hIcon); //CloseHandle(shinfo.hIcon); return myIcon; } public static Icon GetLargeIconFromFile(string FileName, bool jumbo, bool checkDisk) { SHFILEINFO shinfo = new SHFILEINFO(); uint SHGFI_USEFILEATTRIBUTES = 0x000000010; uint SHGFI_SYSICONINDEX = 0x4000; int FILE_ATTRIBUTE_NORMAL = 0x80; uint flags; flags = SHGFI_SYSICONINDEX; if (!checkDisk) // This does not seem to work. If I try it, a folder icon is always returned. flags |= SHGFI_USEFILEATTRIBUTES; var res = SHGetFileInfo(FileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, Marshal.SizeOf(shinfo), flags); if (res == 0) { throw (new System.IO.FileNotFoundException()); } var iconIndex = shinfo.iIcon; // Get the System IImageList object from the Shell: Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950"); IImageList iml; int size = jumbo ? SHIL_JUMBO : SHIL_EXTRALARGE; var hres = SHGetImageList(size, ref iidImageList, out iml); // writes iml //if (hres == 0) //{ // throw (new System.Exception("Error SHGetImageList")); //} IntPtr hIcon = IntPtr.Zero; int ILD_TRANSPARENT = 1; hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon); //if (hres == 0) //{ // throw (new System.Exception("Error iml.GetIcon")); //} var myIcon = System.Drawing.Icon.FromHandle(hIcon); //myIcon.Dispose(); DestroyIcon(hIcon); //CloseHandle(hIcon); return myIcon; } public static Bitmap GetLargeBitmapFromFile(string FileName, bool jumbo, bool checkDisk) { SHFILEINFO shinfo = new SHFILEINFO(); uint SHGFI_USEFILEATTRIBUTES = 0x000000010; uint SHGFI_SYSICONINDEX = 0x4000; int FILE_ATTRIBUTE_NORMAL = 0x80; uint flags; flags = SHGFI_SYSICONINDEX; if (!checkDisk) // This does not seem to work. If I try it, a folder icon is always returned. flags |= SHGFI_USEFILEATTRIBUTES; var res = SHGetFileInfo(FileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, Marshal.SizeOf(shinfo), flags); if (res == 0) { throw (new System.IO.FileNotFoundException()); } var iconIndex = shinfo.iIcon; // Get the System IImageList object from the Shell: Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950"); IImageList iml; int size = jumbo ? SHIL_JUMBO : SHIL_EXTRALARGE; var hres = SHGetImageList(size, ref iidImageList, out iml); // writes iml //if (hres == 0) //{ // throw (new System.Exception("Error SHGetImageList")); //} IntPtr hIcon = IntPtr.Zero; int ILD_TRANSPARENT = 1; hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon); //if (hres == 0) //{ // throw (new System.Exception("Error iml.GetIcon")); //} var myIcon = System.Drawing.Icon.FromHandle(hIcon); Bitmap bm = myIcon.ToBitmap(); myIcon.Dispose(); DestroyIcon(hIcon); //CloseHandle(hIcon); return bm; } } }