Mike Taulty's Blog
Bits and Bytes from Microsoft UK
The Windows Vista Shell, Thumbnails and Managed Code

Blogs

Mike Taulty's Blog

Elsewhere

Archives

Quick update on this post - Ian kindly gave me a nudge and said that running of .NET code inside of the shell might not be supported in that the shell loading COM components implemented in .NET might cause some versioning problems. I'll see if I can find an official answer to that and post it here but, in the meantime, apply a reasonably large dose of salt to the post.

One of the nice features of the Vista shell is its ability to display different sizes of thumbnails based on the actual contents of a document.

So, when I'm looking through a folder of 100's of PowerPoints or Spreadsheets I can actually see what it is I'm looking at in the shell rather than having to open all the documents.

You can plug into this for your own document types by writing an implementation of the interface IThumbnailProvider and returning a bitmap back to the shell for it to use.

I was talking to Andy yesterday and he was mentioning that this interface is an unmanaged COM interface rather than a managed one so I thought I'd have a bash at doing this with .NET and post it here. For unmanaged code, there is already a sample in the SDK called the recipe viewer which shows you how to do this (also, apologies if a managed wrapper came out already and I missed it).

I've built my own document type the .shape file and into a .shape file you can put a little bit of XML such as;

<Shape>

      <Type>CircleType>

      <Color>RedColor>

Shape>

where Type can be Square/Circle/Triangle and the colour can be anything from the named colours selection in .NET.

With a set of documents like this, the shell in Vista can display a folder as below;

and the individual files look like;

(ignore the .xyz extension – took the picture before I changed it to .shape).

In order to display your custom thumbnails like this the shell first comes and initialises your provider using either IInitializeWithStream, IInitialiseWithFile or IInitializeWithItem (depending on how you like to be initialised) and then it calls your implementation of IThumbnailProvider to draw the thumbnail.

To build this from managed code, I went and located the IDL for these two interfaces in thumbcache.idl and shobjidl.idl (in the Windows SDK) and they look something like;

[

    uuid(e357fccd-a995-4576-b01f-234630154e96)

]

interface IThumbnailProvider : IUnknown

{

    HRESULT GetThumbnail([in] UINT cx, [out] HBITMAP *phbmp, [out] WTS_ALPHATYPE *pdwAlpha);

};

and

[

    uuid(b824b49d-22ac-4161-ac8a-9916e8fa3f7f),

    object,

    pointer_default(unique)

]

interface IInitializeWithStream : IUnknown

{

    HRESULT Initialize(

        [in] IStream *pstream,

        [in] DWORD grfMode);

}

and turned them into .NET representations (or approximations!) with something like;

 

  [ComVisible(true)]

  [Guid("e357fccd-a995-4576-b01f-234630154e96")]

  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

  public interface IThumbnailProvider

  {

    void GetThumbnail(uint squareLength,

      out IntPtr hBitmap, out UInt32 bitmapType);

  }

 

  [ComVisible(true)]

  [Guid("b824b49d-22ac-4161-ac8a-9916e8fa3f7f")]

  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

  public interface IInitializeWithStream

  {

    void Initialize(IStream stream, UInt32 grfMode);

  }

In terms of implementing these, I produce a COM class;

 

  [ComVisible(true)]

  [ClassInterface(ClassInterfaceType.None)]

  [ProgId("ThumbnailTest.ThumbnailProvider")]

  [Guid("F039D92E-5EC1-4015-8CA6-CD6F938E2F92")]

  public class ThumbnailProvider : IThumbnailProvider, IInitializeWithStream

  {

and then I need to make sure that's registered properly. The first thing to do is to register the .NET assembly from the point of view of COM using regasm.

In order that COM can find the assembly you can either strongly name and GAC the assembly or you can use the;

regasm /codebase

when you register it to store the DLL location in the registry (a bit naughty but works fine). Either way on Vista don't forget that you'll need to run elevated to make this work.

That's not the only bit of registration you need. You'll also need some registration around the file extension. For my .shape file I need to add a string value under;

HKEY_CLASSES_ROOT\.shape\shellex\{e357fccd-a995-4576-b01f-234630154e96}

with the value of the CLSID of my provider (i.e. {F039D92E-5EC1-4015-8CA6-CD6F938E2F92}) - note that the guid in the key name itself is the GUID of the type of extension we're provider (i.e. it's the GUID for IThumbnailProvider).

I also need to register my provider in;

HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\SHELL EXTENSIONS\APPROVED

and all I do in there is create a string value;


 Name      
 {F039D92E-5EC1-4015-8CA6-CD6F938E2F92}

 Type
 REG_SZ

 Data
 Any descriptive string you like.


With that registration set up, the shell will now start using my ThumbnailProvider in order to represent my .shape files when it comes across them.

I don’t pretend that there’s any kind of “best practise” here but if the code for this is of interest then it’s available here.

If you want to make the existing bits work then build it in your compiler (I built this on Windows Vista build 5456) and then go ahead and run the INSTALL.BAT file that lives in the solution folder. This will attempt to register the COM component and to make the right registration bits appear in your registry.

Note – if your Vista shell seems not to display these thumbnails after this registration, try updating one of the .shape files in the offchance that Vista has cached the previous previews it has for the file.

Next, I’ll see if I can build a managed Preview handler as well and post that here when I’ve got it.

 


Posted Fri, Jul 21 2006 7:52 AM by mtaulty

Comments

UberDemo wrote Building a recipe application using Vista and .NET 3.0 (Part III: Using Windows Vista and .NET 3.0 features)
on Wed, Feb 28 2007 11:29 AM
Displaying a custom Thumbnail in the shell The next thing that I wanted to do was to have a Thumbnail
Vista Shell Extensions in .NET « The Mika Connection wrote Vista Shell Extensions in .NET &laquo; The Mika Connection
on Thu, Dec 27 2007 10:50 AM