vbAccelerator - Contents of code file: ThumbnailTester\ThumbnailCreator.csusing System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace vbAccelerator.Components.Shell
{
#region ThumbnailCreator
/// <summary>
/// Summary description for ThumbnailCreator.
/// </summary>
public class ThumbnailCreator : IDisposable
{
#region ShellFolder Enumerations
[Flags]
private enum ESTRRET : int
{
STRRET_WSTR = 0x0000, // Use STRRET.pOleStr
STRRET_OFFSET = 0x0001, // Use STRRET.uOffset to Ansi
STRRET_CSTR = 0x0002 // Use STRRET.cStr
}
[Flags]
private enum ESHCONTF : int
{
SHCONTF_FOLDERS = 32,
SHCONTF_NONFOLDERS = 64,
SHCONTF_INCLUDEHIDDEN = 128
}
[Flags]
private enum ESHGDN : int
{
SHGDN_NORMAL = 0,
SHGDN_INFOLDER = 1,
SHGDN_FORADDRESSBAR = 16384,
SHGDN_FORPARSING = 32768
}
[Flags]
private enum ESFGAO : int
{
SFGAO_CANCOPY = 1,
SFGAO_CANMOVE = 2,
SFGAO_CANLINK = 4,
SFGAO_CANRENAME = 16,
SFGAO_CANDELETE = 32,
SFGAO_HASPROPSHEET = 64,
SFGAO_DROPTARGET = 256,
SFGAO_CAPABILITYMASK = 375,
SFGAO_LINK = 65536,
SFGAO_SHARE = 131072,
SFGAO_READONLY = 262144,
SFGAO_GHOSTED = 524288,
SFGAO_DISPLAYATTRMASK = 983040,
SFGAO_FILESYSANCESTOR = 268435456,
SFGAO_FOLDER = 536870912,
SFGAO_FILESYSTEM = 1073741824,
SFGAO_HASSUBFOLDER = -2147483648,
SFGAO_CONTENTSMASK = -2147483648,
SFGAO_VALIDATE = 16777216,
SFGAO_REMOVABLE = 33554432,
SFGAO_COMPRESSED = 67108864
}
#endregion
#region IExtractImage Enumerations
private enum EIEIFLAG
{
IEIFLAG_ASYNC = 0x0001, // ask the extractor if it supports
ASYNC extract (free threaded)
IEIFLAG_CACHE = 0x0002, // returned from the extractor if
it does NOT cache the thumbnail
IEIFLAG_ASPECT = 0x0004, // passed to the extractor to beg
it to render to the aspect ratio of the supplied rect
IEIFLAG_OFFLINE = 0x0008, // if the extractor shouldn't hit
the net to get any content neede for the rendering
IEIFLAG_GLEAM = 0x0010, // does the image have a gleam ?
this will be returned if it does
IEIFLAG_SCREEN = 0x0020, // render as if for the screen
(this is exlusive with IEIFLAG_ASPECT )
IEIFLAG_ORIGSIZE = 0x0040, // render to the approx size
passed, but crop if neccessary
IEIFLAG_NOSTAMP = 0x0080, // returned from the extractor if
it does NOT want an icon stamp on the thumbnail
IEIFLAG_NOBORDER = 0x0100, // returned from the extractor if
it does NOT want an a border around the thumbnail
IEIFLAG_QUALITY = 0x0200 // passed to the Extract method to
indicate that a slower, higher quality image is desired, re-compute
the thumbnail
}
#endregion
#region ShellFolder Structures
[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0,
CharSet=CharSet.Auto)]
private struct STRRET_CSTR
{
public ESTRRET uType;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray,
SizeConst=520)]
public byte[] cStr;
}
[StructLayout(LayoutKind.Explicit, CharSet=CharSet.Auto)]
private struct STRRET_ANY
{
[FieldOffset(0)]
public ESTRRET uType;
[FieldOffset(4)]
public IntPtr pOLEString;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
private struct SIZE
{
public int cx;
public int cy;
}
#endregion
#region Com Interop for IUnknown
[ComImport, Guid("00000000-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IUnknown
{
[PreserveSig]
IntPtr QueryInterface(ref Guid riid, out IntPtr pVoid);
[PreserveSig]
IntPtr AddRef();
[PreserveSig]
IntPtr Release();
}
#endregion
#region COM Interop for IMalloc
[ComImportAttribute()]
[GuidAttribute("00000002-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
//helpstring("IMalloc interface")
private interface IMalloc
{
[PreserveSig]
IntPtr Alloc(int cb);
[PreserveSig]
IntPtr Realloc(
IntPtr pv,
int cb);
[PreserveSig]
void Free(IntPtr pv);
[PreserveSig]
int GetSize(IntPtr pv);
[PreserveSig]
int DidAlloc(IntPtr pv);
[PreserveSig]
void HeapMinimize();
};
#endregion
#region COM Interop for IEnumIDList
[ComImportAttribute()]
[GuidAttribute("000214F2-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
//helpstring("IEnumIDList interface")
private interface IEnumIDList
{
[PreserveSig]
int Next(
int celt,
ref IntPtr rgelt,
out int pceltFetched);
void Skip(
int celt);
void Reset();
void Clone(
ref IEnumIDList ppenum);
};
#endregion
#region COM Interop for IShellFolder
[ComImportAttribute()]
[GuidAttribute("000214E6-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
//helpstring("IShellFolder interface")
private interface IShellFolder
{
void ParseDisplayName(
IntPtr hwndOwner,
IntPtr pbcReserved,
[MarshalAs(UnmanagedType.LPWStr)] string lpszDisplayName,
out int pchEaten,
out IntPtr ppidl,
out int pdwAttributes);
void EnumObjects(
IntPtr hwndOwner,
[MarshalAs(UnmanagedType.U4)] ESHCONTF grfFlags,
ref IEnumIDList ppenumIDList
);
void BindToObject(
IntPtr pidl,
IntPtr pbcReserved,
ref Guid riid,
ref IShellFolder ppvOut);
void BindToStorage(
IntPtr pidl,
IntPtr pbcReserved,
ref Guid riid,
IntPtr ppvObj
);
[PreserveSig]
int CompareIDs(
IntPtr lParam,
IntPtr pidl1,
IntPtr pidl2);
void CreateViewObject(
IntPtr hwndOwner,
ref Guid riid,
IntPtr ppvOut);
void GetAttributesOf(
int cidl,
IntPtr apidl,
[MarshalAs(UnmanagedType.U4)] ref ESFGAO rgfInOut);
void GetUIObjectOf(
IntPtr hwndOwner,
int cidl,
ref IntPtr apidl,
ref Guid riid,
out int prgfInOut,
ref IUnknown ppvOut);
void GetDisplayNameOf(
IntPtr pidl,
[MarshalAs(UnmanagedType.U4)] ESHGDN uFlags,
ref STRRET_CSTR lpName);
void SetNameOf(
IntPtr hwndOwner,
IntPtr pidl,
[MarshalAs(UnmanagedType.LPWStr)] string lpszName,
[MarshalAs(UnmanagedType.U4)] ESHCONTF uFlags,
ref IntPtr ppidlOut);
};
#endregion
#region COM Interop for IExtractImage
[ComImportAttribute()]
[GuidAttribute("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
//helpstring("IExtractImage"),
private interface IExtractImage
{
void GetLocation(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder
pszPathBuffer,
int cch,
ref int pdwPriority,
ref SIZE prgSize,
int dwRecClrDepth,
ref int pdwFlags);
void Extract(
out IntPtr phBmpThumbnail);
}
#endregion
#region UnManagedMethods for IShellFolder
private class UnManagedMethods
{
[DllImport("shell32", CharSet = CharSet.Auto)]
internal extern static int SHGetMalloc(out IMalloc ppMalloc);
[DllImport("shell32", CharSet = CharSet.Auto)]
internal extern static int SHGetDesktopFolder(out IShellFolder ppshf);
[DllImport("shell32", CharSet = CharSet.Auto)]
internal extern static int SHGetPathFromIDList (
IntPtr pidl,
StringBuilder pszPath);
[DllImport("gdi32", CharSet = CharSet.Auto)]
internal extern static int DeleteObject (
IntPtr hObject
);
}
#endregion
#region Member Variables
private IMalloc alloc = null;
private bool disposed = false;
private System.Drawing.Size desiredSize = new
System.Drawing.Size(100,100);
private System.Drawing.Bitmap thumbNail = null;
#endregion
#region Implementation
public System.Drawing.Bitmap ThumbNail
{
get
{
return thumbNail;
}
}
public System.Drawing.Size DesiredSize
{
get
{
return desiredSize;
}
set
{
desiredSize = value;
}
}
private IMalloc Allocator
{
get
{
if (!disposed)
{
if (alloc == null)
{
UnManagedMethods.SHGetMalloc(out alloc);
}
}
else
{
System.Diagnostics.Debug.Assert(false, "Object has been
disposed.");
}
return alloc;
}
}
public System.Drawing.Bitmap GetThumbNail(
string file
)
{
if ((!File.Exists(file)) && (!Directory.Exists(file)))
{
throw new FileNotFoundException(
String.Format("The file '{0}' does not exist", file),
file);
}
if (thumbNail != null)
{
thumbNail.Dispose();
thumbNail = null;
}
IShellFolder folder = null;
try
{
folder = getDesktopFolder;
}
catch (Exception ex)
{
throw ex;
}
if (folder != null)
{
IntPtr pidlMain = IntPtr.Zero;
try
{
int cParsed = 0;
int pdwAttrib = 0;
string filePath = Path.GetDirectoryName(file);
pidlMain = IntPtr.Zero;
folder.ParseDisplayName(
IntPtr.Zero,
IntPtr.Zero,
filePath,
out cParsed,
out pidlMain,
out pdwAttrib);
}
catch (Exception ex)
{
Marshal.ReleaseComObject(folder);
throw ex;
}
if (pidlMain != IntPtr.Zero)
{
// IShellFolder:
Guid iidShellFolder = new
Guid("000214E6-0000-0000-C000-000000000046");
IShellFolder item = null;
try
{
folder.BindToObject(pidlMain, IntPtr.Zero, ref
iidShellFolder, ref item);
}
catch (Exception ex)
{
Marshal.ReleaseComObject(folder);
Allocator.Free(pidlMain);
throw ex;
}
if (item != null)
{
//
IEnumIDList idEnum = null;
try
{
item.EnumObjects(
IntPtr.Zero,
(ESHCONTF.SHCONTF_FOLDERS |
ESHCONTF.SHCONTF_NONFOLDERS),
ref idEnum);
}
catch (Exception ex)
{
Marshal.ReleaseComObject(folder);
Allocator.Free(pidlMain);
throw ex;
}
if (idEnum != null)
{
// start reading the enum:
int hRes = 0;
IntPtr pidl = IntPtr.Zero;
int fetched = 0;
bool complete = false;
while (!complete)
{
hRes = idEnum.Next(1, ref pidl, out fetched);
if (hRes != 0)
{
pidl = IntPtr.Zero;
complete = true;
}
else
{
if (getThumbNail(file, pidl, item))
{
complete = true;
}
}
if (pidl != IntPtr.Zero)
{
Allocator.Free(pidl);
}
}
Marshal.ReleaseComObject(idEnum);
}
Marshal.ReleaseComObject(item);
}
Allocator.Free(pidlMain);
}
Marshal.ReleaseComObject(folder);
}
return thumbNail;
}
private bool getThumbNail(
string file,
IntPtr pidl,
IShellFolder item
)
{
IntPtr hBmp = IntPtr.Zero;
IExtractImage extractImage = null;
try
{
string pidlPath = PathFromPidl(pidl);
if
(Path.GetFileName(pidlPath).ToUpper().Equals(Path.GetFileName(file)
.ToUpper()))
{
// we have the item:
IUnknown iunk = null;
int prgf = 0;
Guid iidExtractImage = new
Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1");
item.GetUIObjectOf(
IntPtr.Zero,
1,
ref pidl,
ref iidExtractImage,
out prgf,
ref iunk);
extractImage = (IExtractImage)iunk;
if (extractImage != null)
{
Console.WriteLine("Got an IExtractImage object!");
SIZE sz = new SIZE();
sz.cx = desiredSize.Width;
sz.cy = desiredSize.Height;
StringBuilder location = new StringBuilder(260, 260);
int priority = 0;
int requestedColourDepth = 32;
EIEIFLAG flags = EIEIFLAG.IEIFLAG_ASPECT |
EIEIFLAG.IEIFLAG_SCREEN;
int uFlags = (int)flags;
extractImage.GetLocation(
location,
location.Capacity,
ref priority,
ref sz,
requestedColourDepth,
ref uFlags);
extractImage.Extract(out hBmp);
if (hBmp != IntPtr.Zero)
{
// create the image object:
thumbNail = System.Drawing.Bitmap.FromHbitmap(hBmp);
// is thumbNail owned by the Bitmap?
}
Marshal.ReleaseComObject(extractImage);
extractImage = null;
}
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
if (hBmp != IntPtr.Zero)
{
UnManagedMethods.DeleteObject(hBmp);
}
if (extractImage != null)
{
Marshal.ReleaseComObject(extractImage);
}
throw ex;
}
}
private string PathFromPidl(
IntPtr pidl
)
{
StringBuilder path = new StringBuilder(260, 260);
int result = UnManagedMethods.SHGetPathFromIDList(pidl, path);
if (result == 0)
{
return string.Empty;
}
else
{
return path.ToString();
}
}
private IShellFolder getDesktopFolder
{
get
{
IShellFolder ppshf;
int r = UnManagedMethods.SHGetDesktopFolder(out ppshf);
return ppshf;
}
}
#endregion
#region Constructor, Destructor, Dispose
public ThumbnailCreator()
{
}
public void Dispose()
{
if (!disposed)
{
if (alloc != null)
{
Marshal.ReleaseComObject(alloc);
}
alloc = null;
if (thumbNail != null)
{
thumbNail.Dispose();
}
disposed = true;
}
}
~ThumbnailCreator()
{
Dispose();
}
#endregion
}
#endregion
}
|
|