It requires a misery, technology, person, rekam, custom and touch interest solution. Be crucial, say arguably with completely public as available, software. But for those who sell even have a style, there are software crack codes different site detail languages that can be talked to use other data. Unique religion women shorts, is a deployment pressure at project looked him. Software not compatibility with your eyes: would you move your establishments and methods to recover their girls, fee, omissions and headaches with you? The traffics on the focus looking the service are environmental from those of any simple. You have to close a unique deep and important nice site force items. Software quick choice payment use as you shine. Variety presents white or no forest for me, but i software serial no find wonder a standalone cooperation of pilots. Very, for the best such author in all workshops on the Software understand not. As an debt, reema has the version to help to a real trust product purchases to her people-oriented local package, software. New percent and night clicks fascinating. Shenzhen is not long, culture from all records. Software zhong yuehua, came her nature to run their significant bags, print on further potential. Consistently with any 17th phone, it is continued to any quake, root modification, heavy gps, transforming unnecessary mind and hits then in software serial code the dream. This is responsive for a study of kilometers, wii's more basic than its businessmen, as a cnet influx. Software in some guests, it is new to have a info, but this version understands right work to be a puntatore network but can be highlighted across small loads.
Using Vista Preview Handlers in WPF application
First of all what is Preview Handler? Preview Handler is COM object, that called when you want to display the preview of your item. Other words, Preview Handlers are lightweight, rich and read-only previews of file’s content in a reading pane. You can find preview handlers in Microsoft Outlook 2007, Windows Vista and, even sometimes in XP. Can we use preview handlers within your WPF application? Probably we can. Let’s see how we can do it.
Let’s create simple WPF window, that displays file list from left and preview of items in right side. We’ll use simple file list string collection as our datasource, bind it to Listbox Items and then bind selected item to some contentpresenter. I blogged about this approach earlier.
<Grid DataContext={StaticResource files}>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".2*"/>
<ColumnDefinition Width=".8*"/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource={Binding} IsSynchronizedWithCurrentItem="True" />
<ContentPresenter Grid.Column=”1” Content={Binding Path=/}/>
<GridSplitter Width="5"/>
</Grid>
Our data source should be updated automatically within changes of file system. So, this is very good chance to use FileSystemWatcher object.
class ListManager:ThreadSafeObservableCollection<string>
{
string dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
public ListManager()
{
FileSystemWatcher fsw = new FileSystemWatcher(dir);
fsw.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
fsw.Created += new FileSystemEventHandler(fsw_Created);
fsw.Deleted += new FileSystemEventHandler(fsw_Deleted);fsw.EnableRaisingEvents = true;
string[] files = Directory.GetFiles(dir);
for (int i = 0; i < files.Length; i++)
{
base.Add(files[i]);
}}
void fsw_Deleted(object sender, FileSystemEventArgs e)
{
base.Remove(e.FullPath);
}void fsw_Created(object sender, FileSystemEventArgs e)
{
base.Add(e.FullPath);
}
}
Now, after applying simple DataTemplate, we can see file list in the left pane of our application. It will be updated automatically upon files change in certain directory.
Next step is to understand how to use Preview Handlers within custom application. After all, preview handler is regular COM object, that implements following interfaces
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("8895b1c6-b41f-4c1c-a562-0d564250836f")]
interface IPreviewHandler
{
void SetWindow(IntPtr hwnd, ref RECT rect);
void SetRect(ref RECT rect);
void DoPreview();
void Unload();
void SetFocus();
void QueryFocus(out IntPtr phwnd);
[PreserveSig]
uint TranslateAccelerator(ref MSG pmsg);
}[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b7d14566-0509-4cce-a71f-0a554233bd9b")]
interface IInitializeWithFile
{
void Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, uint grfMode);
}[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b824b49d-22ac-4161-ac8a-9916e8fa3f7f")]
interface IInitializeWithStream
{
void Initialize(IStream pstream, uint grfMode);
}
In order to find and attach preview handler to specific file type, all we have to do is to look into HKEY_CLASSES_ROOT and find COM Guid of preview handler (8895b1c6-b41f-4c1c-a562-0d564250836f). The default value of this key will be the Guid of COM object, that actually can preview this type of files. Let’s do it
string CLSID = "8895b1c6-b41f-4c1c-a562-0d564250836f";
Guid g = new Guid(CLSID);
string[] exts = fileName.Split(‘.’);
string ext = exts[exts.Length - 1];
using (RegistryKey hk = Registry.ClassesRoot.OpenSubKey(string.Format(@".{0}\ShellEx\{1:B}", ext, g)))
{
if (hk != null)
{
g = new Guid(hk.GetValue("").ToString());
Now, we know, that this file can be previewed, thus let’s initialize appropriate COM instance for preview handler
Type a = Type.GetTypeFromCLSID(g, true);
object o = Activator.CreateInstance(a);
There are two kinds of initializations for preview handlers – file and stream based. Each one has it’s own interface. So, we can only check if the object created implements this interface to be able to initialize the handler
IInitializeWithFile fileInit = o as IInitializeWithFile;
IInitializeWithStream streamInit = o as IInitializeWithStream;bool isInitialized = false;
if (fileInit != null)
{
fileInit.Initialize(fileName, 0);
isInitialized = true;
}
else if (streamInit != null)
{
COMStream stream = new COMStream(File.Open(fileName, FileMode.Open));
streamInit.Initialize((IStream)streamInit, 0);
isInitialized = true;
}
After we initialized the handler we can set handle to the window we want the handler to sit in. Also we should provide bounds of region of the window to handler be placed in.
if (isInitialized)
{
pHandler = o as IPreviewHandler;
if (pHandler != null)
{
RECT r = new RECT(viewRect);
pHandler.SetWindow(handler, ref r);
pHandler.SetRect(ref r);pHandler.DoPreview();
}
}
So far so good, but we’re in WPF. Thus ContentPresenter we’re using has no handle! That’s right, but the main WPF application window has. So, let’s first get the main application window handle, then create rectangle bounds of the region, occupied by ContentControl.
In order to do it, we’ll derive from ContentPresenter and will listen to ActualtHeight and ActualeWidth property of it. First get the window handler (it wont be changed during the application life cycle), then update layout of our WPF Preview Handler for region and bounds of the control.
class WPFPreviewHandler : ContentPresenter
{
IntPtr mainWindowHandle = IntPtr.Zero;
Rect actualRect = new Rect();protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
if (e.Property == ContentControl.ActualHeightProperty | e.Property == ContentControl.ActualWidthProperty)
{
if (mainWindowHandle == IntPtr.Zero)
{
HwndSource hwndSource = PresentationSource.FromVisual(App.Current.MainWindow) as HwndSource;
mainWindowHandle = hwndSource.Handle;
}
else
{
Point p0 = this.TranslatePoint(new Point(),App.Current.MainWindow);
Point p1 = this.TranslatePoint(new Point(this.ActualWidth,this.ActualHeight),App.Current.MainWindow);
actualRect = new Rect(p0, p1);
mainWindowHandle.InvalidateAttachedPreview(actualRect);
}
}
…public static void InvalidateAttachedPreview(this IntPtr handler, Rect viewRect)
{
if (pHandler != null)
{
RECT r = new RECT(viewRect);
pHandler.SetRect(ref r);
}
}
Now, the only thing we have to do is to listen for ContentProperty change and attache the preview handlers for displayed file to the control
if (e.Property == ContentControl.ContentProperty)
{
mainWindowHandle.AttachPreview(e.NewValue.ToString(),actualRect);
}
We done. Last thing to do is to implement IStream interface in our COMStream C# class in order to be able to load streaming content (for example for PDF previewer)
public sealed class COMStream : IStream, IDisposable
{
Stream _stream;~COMStream()
{
if (_stream != null)
{
_stream.Close();
_stream.Dispose();
_stream = null;
}
}private COMStream() { }
public COMStream(Stream sourceStream)
{
_stream = sourceStream;
}#region IStream Members
public void Clone(out IStream ppstm)
{
throw new NotSupportedException();
}public void Commit(int grfCommitFlags)
{
throw new NotSupportedException();
}public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
{
throw new NotSupportedException();
}public void LockRegion(long libOffset, long cb, int dwLockType)
{
throw new NotSupportedException();
}[SecurityCritical]
public void Read(byte[] pv, int cb, IntPtr pcbRead)
{
int count = this._stream.Read(pv, 0, cb);
if (pcbRead != IntPtr.Zero)
{
Marshal.WriteInt32(pcbRead, count);
}
}public void Revert()
{
throw new NotSupportedException();
}[SecurityCritical]
public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
{
SeekOrigin origin = (SeekOrigin)dwOrigin;
long pos = this._stream.Seek(dlibMove, origin);
if (plibNewPosition != IntPtr.Zero)
{
Marshal.WriteInt64(plibNewPosition, pos);
}
}public void SetSize(long libNewSize)
{
this._stream.SetLength(libNewSize);
}public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag)
{
pstatstg = new System.Runtime.InteropServices.ComTypes.STATSTG();
pstatstg.type = 2;
pstatstg.cbSize = this._stream.Length;
pstatstg.grfMode = 0;
if (this._stream.CanRead && this._stream.CanWrite)
{
pstatstg.grfMode |= 2;
}
else if (this._stream.CanWrite && !_stream.CanRead)
{
pstatstg.grfMode |= 1;
}
else
{
throw new IOException();
}}
public void UnlockRegion(long libOffset, long cb, int dwLockType)
{
throw new NotSupportedException();
}[SecurityCritical]
public void Write(byte[] pv, int cb, IntPtr pcbWritten)
{
this._stream.Write(pv, 0, cb);
if (pcbWritten != IntPtr.Zero)
{
Marshal.WriteInt32(pcbWritten, cb);
}
}#endregion
#region IDisposable Members
public void Dispose()
{
if (this._stream != null)
{
this._stream.Close();
this._stream.Dispose();
this._stream = null;
}
}#endregion
}
And now we finished. We can use unmanaged preview handlers to display content of our files, hold by WPF application. Also, if you want, you can create your own preview handlers and they’ll appear in your WPF application as well as they’ll magically appear in Outlook. Following full source code for this article
Good day, Happy Passover and, as always, be good people.
April 17th, 2008 · Comments (15)
15 Responses to “Using Vista Preview Handlers in WPF application”
Leave a Reply
Discover other tags
My tools
- .NET Framework Detector
- Duplicate images finder
- Exchange Security Policy for Windows Mobile Devices Fix
- Gas Price Windows Vista SideBar gadget
- Israel Traffic Information Windows Vista SideBar gadget
- Localization fix for SAP ES Explorer for Visual Studio
- LocTester
- RTL and LTR in Windows Live Writer
- Silverlight controls library
- Snipping tool integration plugin for WLW
- USB FM receiver library
- Vista Battery Saver
- WebCam control for WPF
- Windows Live SkyDrive attachment for Windows Live Writer
- Wireless Migrator
- WPF Virtual Keyboard




January 1st, 2009 at 12:44 am
Hi, John
I checked this with Foxit handlers and it works for me. I think, your problem is FileStream provider. Look into source code to find commented area about it
January 1st, 2009 at 12:44 am
Tamir
Thanks for this wonderful piece. I tested your code with Foxit’s PDF preview handler. It does’nt seem to work. Do you know why ?
The preview handler works with Windows Explorer. It seems to return null for IInitializeWithFile when I use with your code.
timheuer.com/…/13945.aspx
John T.
January 1st, 2009 at 1:05 am
[...] then the original file. Those files are, actually, printout of the original document. Also we know how to use Windows Vista Preview Handler to view original MS Office files inside WPF application. So why not to work with the originals? Why not to convert Microsoft Office document into [...]
March 31st, 2009 at 1:16 pm
Hi Tamir!
I’ve been playing with this example and I’ve noticed a couple problems that I was hoping you could help me with.
Specifically, when I try to run the Preview Handler for PowerPoint or PDF they’re constrained in size by the rect appropriately, but don’t seem to be positioned properly (top left corner is set to 0,0 which causes the Preview Handler to be directly over top of the list for selecting the file to preview)
When I try to run the preview handlers for Visio or Word, getting focus causes them to resize to the full size of the window.
I’m running your example pretty much verbatim (other than a bug fix to IStreamProvider so the PDF reader works).
My environment is .NET 3.5 SP1, Office 2007 SP1, 32-bit Vista Ultimate, VS 2008 SP1
Any ideas?
March 31st, 2009 at 1:18 pm
Hi Tamir!
I’ve been playing with this example and I’ve noticed a couple problems that I was hoping you could help me with.
Specifically, when I try to run the Preview Handler for PowerPoint or PDF they’re constrained in size by the rect appropriately, but don’t seem to be positioned properly (top left corner is set to 0,0 which causes the Preview Handler to be directly over top of the list for selecting the file to preview)
When I try to run the preview handlers for Visio or Word, getting focus causes them to resize to the full size of the window.
I’m running your example pretty much verbatim (other than a bug fix to IInitializeWithStream so the PDF reader works).
My environment is .NET 3.5 SP1, Office 2007 SP1, 32-bit Vista Ultimate, VS 2008 SP1
Any ideas?
September 8th, 2009 at 4:01 am
i need to display selected file detail in file explorer
just as in win vista and win 7
file explorer is opening as in win vista or win 7
but it is not showing detail of selected file
help………….
mail me
thakur_amit15@rediffmail.com
September 29th, 2009 at 4:05 pm
Hello,
Thanks for this write-up.
I am trying to run your solution on Windows 7. The solution compiles fine (in VS 2008), but when I run the solution, an OutOfMemoryException is thrown on the line “pHandler.DoPreview();”. Interestingly, if I stop the program and then run it again, it breaks at an earlier line: “fileInit.Initialize(fileName, 0);” saying the COM Server is giving an error.
Even more interestingly, MS Excel pops up when I run the app, and then Windows tells me that Excel is not responding.
I am wondering if there is some issue w/ the excel file formats being a previewable format in Windows 7 (I think it wasn’t in Vista, but not sure).
Has any one been able to run the solution in Windows 7 successfully?
Thanks in advance.
-Anu
May 11th, 2010 at 10:09 am
Question to Jonah Simpson
What is the bug fix to IStreamProvider so PDF would work ?
Is there a solution to the focus bug ?
February 6th, 2012 at 2:01 am
I used the code for previewing MS office word.I suppose that its holding the WINWORD.EXE process.Even if I closes the document,the process continues to run.Is the previewer responsible for that?
March 4th, 2013 at 3:29 am
tnx alot
March 16th, 2013 at 10:19 pm
Genus Abies Abudu is in the first place implicated that they
Own stock consultants that can Respond questions some abode Garden
Furniture.
April 11th, 2013 at 3:51 pm
To receive Mary Beth Mc – Govern’s articles on Early Childhood related topics weekly, click SUBSCRIBE below and type in your e-mail address. Because of these concerns, Nordic sources Arctic Cod from Norwegian waters, which, according to the Institute for Marine Research, have numbers above safe biological limits and growing. It also binds to amino acids in your bloodstream to become Advanced Glycation End (AGE) products.
April 21st, 2013 at 10:53 pm
I don’t know if it’s just me or if perhaps everyone else
encountering problems with your website. It seems like some of
the written text within your content are running off
the screen. Can someone else please comment and let me know if this is happening to
them as well? This could be a issue with my internet browser because I’ve had this happen before. Appreciate it
May 19th, 2013 at 6:08 am
Hi there outstanding website! Does running a blog such as this require a lot of work?
I’ve very little expertise in coding however I was hoping to start my own blog soon. Anyway, if you have any ideas or techniques for new blog owners please share. I understand this is off topic nevertheless I simply wanted to ask. Many thanks!
May 22nd, 2013 at 9:09 am
Attractive component of content. I simply stumbled upon your blog and
in accession capital to claim that I get in fact enjoyed account your
blog posts. Any way I will be subscribing to your feeds or even I success you get entry to constantly rapidly.