I'm trying to make use of Window's ThumbnailCache in a WPF application. I'm starting with a path to an image file and hoping to end up with a Media.Imaging.BitmapImage that holds the thumbnail.
I've been piecing things together, but I'm starting to think I'm on the wrong track. This feels like a lot of code to do what ought to be straightforward.
Am I on the wrong track with this?
public BitmapImage Thumbnail { get; set; }
private void LoadThumbnail()
{
IShellItem shellItem;
SHCreateItemFromParsingName(FilePath, IntPtr.Zero, typeof(IShellItem).GUID, out shellItem);
IntPtr hBitmap = IntPtr.Zero;
((IShellItemImageFactory)shellItem).GetImage(new SIZE(256, 256), 0x0, out hBitmap);
try
{
BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
BitmapImage bitmapImage = new BitmapImage();
??? BitmapImage from BitmapSource...
Thumbnail = bitmapImage;
}
finally
{
DeleteObject(hBitmap);
}
}
[DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
public static extern void SHCreateItemFromParsingName(
[In][MarshalAs(UnmanagedType.LPWStr)] string pszPath,
[In] IntPtr pbc,
[In][MarshalAs(UnmanagedType.LPStruct)] Guid riid,
[Out][MarshalAs(UnmanagedType.Inte开发者_如何学Gorface, IidParameterIndex = 2)] out IShellItem ppv);
[ComImportAttribute()]
[GuidAttribute("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellItemImageFactory
{
void GetImage(
[In, MarshalAs(UnmanagedType.Struct)] SIZE size,
[In] SIIGBF flags,
[Out] out IntPtr phbm);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
public interface IShellItem
{
void BindToHandler(IntPtr pbc,
[MarshalAs(UnmanagedType.LPStruct)]Guid bhid,
[MarshalAs(UnmanagedType.LPStruct)]Guid riid,
out IntPtr ppv);
void GetParent(out IShellItem ppsi);
void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
void Compare(IShellItem psi, uint hint, out int piOrder);
};
[StructLayout(LayoutKind.Sequential)]
public struct SIZE
{
public int cx;
public int cy;
public SIZE(int cx, int cy)
{
this.cx = cx;
this.cy = cy;
}
}
[Flags]
public enum SIIGBF
{
SIIGBF_RESIZETOFIT = 0x00,
SIIGBF_BIGGERSIZEOK = 0x01,
SIIGBF_MEMORYONLY = 0x02,
SIIGBF_ICONONLY = 0x04,
SIIGBF_THUMBNAILONLY = 0x08,
SIIGBF_INCACHEONLY = 0x10,
}
public enum SIGDN : uint
{
NORMALDISPLAY = 0,
PARENTRELATIVEPARSING = 0x80018001,
PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
DESKTOPABSOLUTEPARSING = 0x80028000,
PARENTRELATIVEEDITING = 0x80031001,
DESKTOPABSOLUTEEDITING = 0x8004c000,
FILESYSPATH = 0x80058000,
URL = 0x80068000
}
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
There is an open source library for reading thumbs.db files available here:
http://www.petedavis.net/drupal//index.php?q=node/2
It includes full sourcecode. Might be easier than trying to do-it-yourself!
精彩评论