rpowers WebLog

Musings on Agile Development and Visual Studio ALM Tools
in

Hosting Vista File Previews in Managed Code

As part of my work on the Coding4Fun Developer Kit 2008, I created a WinForm control encapsulating the flow to display file previews.  The host is dependent on an improved version of Stephen Toub's framework, originally published here.  My enhancements were basically to make the COM wrapper classes public so that they can be used by the Managed PreviewHandlers and also by my Preview Handler Host.  The source for this project including the updated framework, Stephen's sample preview handlers, my host control and a sample application using the host control are available here.  Also, they can be downloaded from the codeplex project for the Coding4Fun Developer Kit 2008.

A couple of quick notes before I describe how the managed preview handler host works. 

  1. For any of this to work, the C4F.DevKit.PreviewHandlerFramework.dll needs to be installed in GAC.
  2. Also, this host will work with all non-managed preview handlers and any managed preview handlers that were built against the PreviewHandlerFramework mentioned above.  Any Managed Preview Handlers that were compiled using Stephen's original framework or another method will not work with this host. 

 

To host the results generated by any registered file preview handler in managed code, the PreviewHandlerFramework’s COM Wrappers are leveraged. In addition, part of this host needs to look up the preview handler that is currently registered with a particular file extension. To accomplish this, the PreviewHandlerHost leveraged the registry code from Stephen Toub’s Preview Handler Association Editor (http://blogs.msdn.com/toub/archive/2006/12/14/preview-handler-association-editor.aspx). With the code to find the registered handler in hand, we constructed a control to implement the preview handler Data Flow as shown below (all of this code is part of PreviewHandlerHost project, PreviewHandlerHostControl.cs):

  • Declare an object that is the PreviewHandler (this will be cast to different COM Interfaces as needed)
  • Unload any existing previews before generating a new preview
    • Call Unload of IPreviewHandler Interface (dDefined in PreviewHandlerFramework as a wrapper to existing COM interface)

Visual C#

private object _comInstance = null; private void GeneratePreview() { if (_comInstance != null) { ((IPreviewHandler)_comInstance).Unload(); }

Visual Basic

 

Private _filePath As String Private Sub GeneratePreview() If Not _comInstance Is Nothing Then CType(_comInstance, IPreviewHandler).Unload() End If
  • Build a RECT struct using the bounds of the visible area where the preview handler can draw. In this case, that is the full bounds of the PreviewHandlerHostControl

Visual C#

RECT r; r.top = 0; r.bottom = this.Height; r.left = 0; r.right = this.Width;

Visual Basic

 

Dim r As RECT r.top = 0 r.bottom = Me.Height r.left = 0 r.right = Me.Width

  • Find the CLSID of the preview handler registered for the file extension of the file using registry lookup. This is typically done by looking in the registry under HKEY_CLASSES_ROOT\%file_extension%\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}. This Registry key will have a value pointed to the Class ID (CLSID) of the COM registration of the registered preview handler. For more information about how preview handlers can be found in the registry, see this article.
  • Create an instance of the preview handler using Reflection and the CLSID found in the registry.

Visual C#

Type comType = Type.GetTypeFromCLSID(new Guid(handler.ID)); _comInstance = Activator.CreateInstance(comType);

Visual Basic

 

Dim comType As Type = Type.GetTypeFromCLSID(New Guid(handler.ID)) _comInstance = Activator.CreateInstance(comType)

  • Call the appropriate initialize for the create preview handler (either passing in a stream or filepath)
    • If the preview handler is a stream previewhandler, using a COM IStream Wrapper to handle Stream marshalling to COM

Visual C#

if (_comInstance is IInitializeWithFile) { ((IInitializeWithFile)_comInstance).Initialize(_filePath, 0); } else if (_comInstance is IInitializeWithStream) { if (File.Exists(_filePath)) { StreamWrapper stream = new StreamWrapper(File.Open(_filePath, FileMode.Open)); ((VSExpressDevPack.PreviewHandlerFramework.IInitializeWithStream)_comInstance).Initialize(stream, 0); } else { throw new Exception("File not found"); } }

Visual Basic

 

If TypeOf _comInstance Is IInitializeWithFile Then CType(_comInstance, IInitializeWithFile).Initialize(_filePath, 0) ElseIf TypeOf _comInstance Is IInitializeWithStream Then If File.Exists(_filePath) Then Dim stream As StreamWrapper = New StreamWrapper(File.Open(_filePath, FileMode.Open)) CType(_comInstance, VSExpressDevPack.PreviewHandlerFramework.IInitializeWithStream).Initialize(stream, 0) Else Throw New Exception("File not found") End If End If

  • Call SetWindow on the PreviewHandler, passing in a handle to the control and the bounds (RECT created earlier)

Visual C#

((IPreviewHandler)_comInstance).SetWindow(this.Handle, ref r);

Visual Basic

 

CType(_comInstance, IPreviewHandler).SetWindow(Me.Handle, r)
  • Call DoPreview on the PreviewHandler

Visual C#

 

((IPreviewHandler)_comInstance).DoPreview();

Visual Basic

CType(_comInstance, IPreviewHandler).DoPreview()

If you are interested in more information, the zip file included with this project has all of the source and a document describing a walkthrough of using this control.  Additionally, the Coding4Fun Developer Pack 2008 Vol.1 Codeplex project has all the info and will also have any fixes/enhancements.

Comments

Dmitry P said:

Perfect !!!
# January 13, 2008 1:32 PM

credit buildup said:

Nice Site!

http://google.com

# June 30, 2008 12:07 PM

newbie said:

Thank you for this excellent post. I have tried it on my Vista, and it seems to work for Office and PDF files. However, I get the message "No preview available" for jpg, png, gif file types. I don't understand why this would happen, as the Vista explorer preview pane properly shows previews of these file types. Any thoughts or guidance would be much appreciated!

# January 2, 2009 1:58 AM

abjlkNMIaGunw said:

doors.txt;10;15

# September 15, 2009 6:58 AM

sherry william said:

this is really a nice website and i found some useful and informative material on it. I have developed a useful link, <a href="http://www.ccnptests.com">ccnp certification</a> provides you with some interesting information that can be beneficial to you, and you can avail a lot. Please have a look at it.

Thanks

# March 16, 2010 1:01 AM

Orquidea said:

Hi guys. Hi, nice site. Keep up the good work. Help me! I can not find sites on the: Estradiol 17 valerate. I found only this - <a href="bibliosafety.icgeb.org/.../Estradiol">estradiol levels in menopause</a>. Estradiol, after body of the enough human methodology, the use cycle estrogens fix into the fat medicine people of the river palmetto. I'm preventing to revitalize some tabasco before trying it, because this one phytoestrogens to influence some body and area, cervical to resolve, estradiol. :mad: Thanks in advance. Orquidea from Timor.

# April 2, 2010 9:36 AM

Pedro said:

Hello,

The PreviewHandlerHost is great, and very handy, but it is locking the files it previews, do you know why this could be happening?

Thank you  very much

# August 5, 2010 9:36 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)