| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Runtime.InteropServices;
- using System.Windows;
- using System.Windows.Media.Imaging;
- using System.Windows.Media;
- using System.Diagnostics;
- using System.Drawing;
- namespace GeekDesk.Util
- {
- public class WindowsThumbnailProvider
- {
- private struct RECT
- {
- public int Left;
- public int Top;
- public int Right;
- public int Bottom;
- }
- private struct POINT
- {
- public int x;
- public int y;
- }
- // 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 icon_of_path(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 Icon icon_of_path_large(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 myIcon;
- }
- }
- }
|