Introduction
Preview handler is the latest methodology in Microsoft Windows Vista™, which provide a rich, interactive, and read-only preview of a file without having to launch the associated application. The in-place interactive previews of the file are available in the Explorer windows, common dialogs, and search results. The core feature is integrated into Windows Vista Shell which allows developers to extend this functionality by writing managed code add-ins i.e. preview handlers for custom files.
For example, "a Microsoft Word 2007 Preview Handler" will enable a user to view and interact with a Microsoft Word 2007 document (.docx file) without having to launch Microsoft Word 2007. In fact, you don't even need Microsoft Word 2007 or Office 2007 to see the preview if you have the related preview handler - now that's amazing.
This article describes a preview handler for Adobe Photoshop® (PSD) file. Here is how the preview of a PSD file will look like in the preview pane
The goal
When the user clicks on a Photoshop file (vista_adobe.psd) in the Windows Explorer
- A "readonly" preview of the file will be shown in the preview pane
- Image "Dimension" and "number of layers" in the PSD file will be shown in the "tooltip"
- Resolution, Color Depth, & Compression information of the file will be available to the user
All this occurs without the Adobe Photoshop application.
Background
Managed Preview Handler Framework
The preview handler described here uses a Managed Preview Handler Framework MsdnMagPreviewHandlers.dll which was first described by Stephen Toub here. For those of you who want to jump in and view the preview handler in action, you can download the first zip file containing the framework, as well as Photoshop Preview Handler, and follow the ReadMe.txt (included). Here is the overview:
New Shell Interfaces for Windows Vista
An extensive set of COM interfaces have been added to the Shell in Windows Vista™ and greatly extend its built-in capabilities. These interfaces offer such features as: new interfaces that expose functionalities that exist in previous versions of Windows but were not exposed by the shell (such as common file dialogs), and interfaces for new Vista UI components or operating system functionality such as Known Folders, Dynamic Autoplay, and property and preview handlers. Download the complete list in the form of help file here
The following is a list of the new interfaces added to the Shell in Windows Vista to provide methods to work with preview handlers.
IPreviewHandler
IPreviewHandlerFrame
IPreviewHandlerVisuals
IPreviewHostSurrogateClient
IPreviewHostSurrogateSink
Making of the Photoshop Preview Handler
The whole project can be divided into three parts:
- The Managed Preview Handler Framework
- The Photoshop Preview Handler
- The functionality of Photoshop file Parsing
The Managed Preview Handler Framework
Here are the parts of the class diagram, which is of immediate concern for us. More details can be found in Stephen Toub's article
Preview Handler attribute
So what we do is create a class file in managed code and inherit it from the framework as follows:
public sealed class PhotoshopPreviewHandler : FileBasedPreviewHandler
The Photoshop Preview Handler
Using the code
Here is the brief code which gives a bird's eye view of the preview handlers load function. For those of you who want to create a Preview Handler, I will suggest this brilliant screencast by Daniel Moth here . In fact everything you see here I did step by step as shown by Daniel from scratch.
[ProgId("CSharpTricks.PhotoshopPreviewHandler")]
[Guid("BC928906-855C-4a6e-8AB6-78105D355708")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public sealed class PhotoshopPreviewHandler : FileBasedPreviewHandler
{
protected override PreviewHandlerControl CreatePreviewHandlerControl()
{
return new PhotoshopPreviewHandlerControl();
}
private sealed class PSDPreviewHandlerControl:FileBasedPreviewHandlerControl
{
public override void Load(FileInfo file)
{
FileInfo mypsdfile = MakeTemporaryCopy(file);
CPSD psd = new CPSD();
Label label1 = new Label();
PictureBox pictureBox1 = new PictureBox();
pictureBox1.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
int nResult = psd.Load(mypsdfile.FullName);
myToolTip.SetToolTip(pictureBox1, label1.Text);
this.Controls.Add(pictureBox1);
}
If there is an error while parsing the Photoshop file, we have to safely show an error image and not the exception. If you want to test this, create a text file and change the extension to .psd and see the preview pane when that file is selected.
Photoshop File Parsing
Well, now comes the tricky part parsing the Photoshop file. A Photoshop file is just like a binary file with all the information as a mixture of XML and binary data. The first challenge is to get the file format specification because Adobe does not provide that freely. You have to do a request for Photoshop SDK here as well as a separate request for Photoshop File format. The good news is the Photoshop file format has not changed much since version 3.0, so if you get a copy of an old Photoshop file format, you pretty much have the stuff you need. You can also find an old version of the Photoshop File format here.
The following image gives you a glimpse of how it looks.
This is the basic format of how data and information is stored in a PSD file
A file header will give you all the image related information as shown
Image resource block is one of the basic units of the PSD file
This is how data is stored in the Photoshop file; to extract it is another story. When I started my binary data reader object, I came across these excellent articles by ihaml here and Igor Tolmachev here. These articles saved me the time it might take to reinvent the wheel (reinforcing my initial idea of time saving), though I also enhanced their work to get the information of number of layers in the Photoshop file and interact with the way needed by the preview handler.
Here is the code to read the PSD File header as shown (File header image above)
protected bool ReadHeader(FileStream stream)
{
bool bSuccess = false;
BinaryReader binReader = new BinaryReader(stream);
try
{
binReader.BaseStream.Position = 0;
byte [] Signature = binReader.ReadBytes(4);
byte [] Version = binReader.ReadBytes(2);
byte [] Reserved = binReader.ReadBytes(6);
byte [] Channels = binReader.ReadBytes(2);
byte [] Rows = binReader.ReadBytes(4);
byte [] Columns = binReader.ReadBytes(4);
byte [] Depth = binReader.ReadBytes(2);
byte [] Mode = binReader.ReadBytes(2);
ASCIIEncoding encoding = new ASCIIEncoding();
So you create a Photoshop parser, return the file information in a Photoshop Preview handler, which, utilizing the preview handler framework, shows you the image data information for the preview pane.
Points of Interest
- During the development of preview handlers, if you don't see the changes (even after using reinstall.bat) a PC restart solves the problem of detaching the existing version of the preview handler dll and the framework from GAC.
- If you want to create your own preview handler look closely the implementation of MakeTemporaryCopy(file)
- Will add more as I come across, adios
Photoshop Preview Handler in action for Outlook 2007
Some concluding thoughts
Almost all software applications in the world are developed with at least one purpose in mind: "saving time". Be it a Windows application, a Java applet, a shell script, tiny applications hosted in sidebar gadget, a search engine, an e-commerce application, a tic tac toe game (yes! even a simple game), all the projects, products, api's, solutions, services, everything which has been developed for the purpose of saving time. Think about it, software which saves more time is better software. This is one of the reasons why Preview Handlers will be very popular.
References
Article History
- Mar 29, 2007: First published
- Apr 01, 2007: Content revised
And thanks
For coming so far! I hope you find this as useful as I do, and take care.