File preview in windows explorer
-
Anyone knows how to preview a custom file format with a bitmap in windows explorer? For example, the 3D Studio file format (file.3ds) is not a gif or bmp or anything. However, if you select it windows explorer, an image preview of the file pops up on the left anyway just as if it were an image file. How is this done? - Peder -
-
Anyone knows how to preview a custom file format with a bitmap in windows explorer? For example, the 3D Studio file format (file.3ds) is not a gif or bmp or anything. However, if you select it windows explorer, an image preview of the file pops up on the left anyway just as if it were an image file. How is this done? - Peder -
This is done via the
IExtractImage
shell interface. You can find more information about the interface here[^]. If you want to leverage this functionality in your .NET application, see Thumbnail Extraction Using the Shell[^] (something I found quick by googling). If you have created a document format in .NET and want to support this interface, you must declare this interface in your code like this:[Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IExtractImage
{
void GetLocation(
[MarshalAs(UnmanagedType.LPTStr), Out] string path,
[MarshalAs(UnmanagedType.U4), In] int pathSize,
[MarshalAs(UnmanagedType.U4), In, Out] ref int priority,
[In] ref Size size,
[MarshalAs(UnmanagedType.U4), In] int RecClrDepth,
[MarshalAs(UnmanagedType.U4), In, Out] ref int flags);
void Extract(IntPtr hBitmap);
}You implement this interface on a class that also exposes a CLSID (Class ID - use the
GuidAttribute
to explicitly define a CLSID using uuidgen.exe or something). You then register this using regasm.exe from the .NET Framework. The usual regsvr32.exe will not work since an assembly does not export the necessary functions (likeDllRegisterServer
). See Nick's article, Creating a CCW for COM-Enabled, non-.NET Applications[^], for more information on exposing .NET classes as COM components. You would also have to manually register this CLSID under the PersistentHandler registery key under your extension's registry key. This is how the shell determines if your extension supports thumbnails and determines how to load them (using the CLSID of your class). More information about this is available in the Platform SDK. You can make this easier by attributing a couple -
This is done via the
IExtractImage
shell interface. You can find more information about the interface here[^]. If you want to leverage this functionality in your .NET application, see Thumbnail Extraction Using the Shell[^] (something I found quick by googling). If you have created a document format in .NET and want to support this interface, you must declare this interface in your code like this:[Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IExtractImage
{
void GetLocation(
[MarshalAs(UnmanagedType.LPTStr), Out] string path,
[MarshalAs(UnmanagedType.U4), In] int pathSize,
[MarshalAs(UnmanagedType.U4), In, Out] ref int priority,
[In] ref Size size,
[MarshalAs(UnmanagedType.U4), In] int RecClrDepth,
[MarshalAs(UnmanagedType.U4), In, Out] ref int flags);
void Extract(IntPtr hBitmap);
}You implement this interface on a class that also exposes a CLSID (Class ID - use the
GuidAttribute
to explicitly define a CLSID using uuidgen.exe or something). You then register this using regasm.exe from the .NET Framework. The usual regsvr32.exe will not work since an assembly does not export the necessary functions (likeDllRegisterServer
). See Nick's article, Creating a CCW for COM-Enabled, non-.NET Applications[^], for more information on exposing .NET classes as COM components. You would also have to manually register this CLSID under the PersistentHandler registery key under your extension's registry key. This is how the shell determines if your extension supports thumbnails and determines how to load them (using the CLSID of your class). More information about this is available in the Platform SDK. You can make this easier by attributing a coupleThis was very informative and interesting! However, I believe I might have expressed myself a tad unprecise. My question was rather how to enable the preview mode on a file type I create myself. And then, secondly, I suppose the continuation will be to get hold of some image, remove the file headers, and finally embed the image data at some address in the file. Maybe the trick is to make my own derived file class? - Peder -
-
This was very informative and interesting! However, I believe I might have expressed myself a tad unprecise. My question was rather how to enable the preview mode on a file type I create myself. And then, secondly, I suppose the continuation will be to get hold of some image, remove the file headers, and finally embed the image data at some address in the file. Maybe the trick is to make my own derived file class? - Peder -
Yes, and what I said is correct. You must define a persistence handler for your document type and register it. Windows Explorer will use this information to generate a thumbnail. The links I gave you provide you with more information about this process. How your
IExtractImage
implementation gets the image is entirely up to you. For many Microsoft Office types, a thumbnail is generated when the document is saved and stored in the compound document structure. The persistence handler for those document types extracts that image. For support videos in Windows Explorer, theIExtractImage
implementation extacts the frame so many seconds into the movie and uses that for the thumbmail, which is cached in the Thumbs.db. Read the Platform SDK for more information. You can also read Mike Dunn's The Complete Idiot's Guide to Writing Shell Extensions - Part I[^], a step-by-step tutorial on writing shell extensions in C++. There is a whole series. This doesn't cover theIExtractImage
extension, but should give you a basic idea of what I already covered. I also gave you the information you need to know how to implement the shell interface in C# and register your .NET assembly as a CCW, or COM-Callable Wrapper, so that it can be used by the shell to use yourIExtractImage
implementation for your document type.Microsoft MVP, Visual C# My Articles