C#实现Windows资源管理器文件预览
上一篇文章大致介绍了一下C++实现Windows文件预览的方法,这里介绍一下通过.NET方式实现文件预览。
其实原理还是一样,需要通过实现系统定义的COM接口,包括
IInitializeWithFile,IObjectWithSite, IOleWindow,IPreviewHandler
```等
而C#并没有定义这些接口,因此我们需要把这些接口通过System.Runtime.InteropServices先从COM中引进到项目中
<div class="se-preview-section-delimiter"></div>
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid(“8895b1c6-b41f-4c1c-a562-0d564250836f”)]
public interface IPreviewHandler
{
///
/// Sets the parent window of the previewer window, as well as the area within the parent to be used for the previewer window.
///
/// A handle to the parent window.
/// A pointer to a RECT defining the area for the previewer.
/// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
[PreserveSig]
int SetWindow(IntPtr hwnd, ref RECT prc);
/// <summary>
/// Directs the preview handler to change the area within the parent hwnd that it draws into.
/// </summary>
/// <param name="prc">A pointer to a RECT to be used for the preview.</param>
/// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
[PreserveSig]
int SetRect(RECT prc);
/// <summary>
/// Directs the preview handler to load data from the source specified in an earlier Initialize method call, and to begin rendering to the previewer window.
/// </summary>
/// <returns>This method can return one of these values.</returns>
[PreserveSig]
int DoPreview();
/// <summary>
/// Directs the preview handler to cease rendering a preview and to release all resources that have been allocated based on the item passed in during the initialization.
/// </summary>
/// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
[PreserveSig]
int Unload();
/// <summary>
/// Directs the preview handler to set focus to itself.
/// </summary>
/// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
[PreserveSig]
int SetFocus();
/// <summary>
/// Directs the preview handler to return the HWND from calling the GetFocus Function.
/// </summary>
/// <param name="phwnd">When this method returns, contains a pointer to the HWND returned from calling the GetFocus Function from the preview handler"s foreground thread.</param>
/// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
[PreserveSig]
int QueryFocus(out IntPtr phwnd);
/// <summary>
/// Directs the preview handler to handle a keystroke passed up from the message pump of the process in which the preview handler is running.
/// </summary>
/// <param name="pmsg">A pointer to a window message.</param>
/// <returns>If the keystroke message can be processed by the preview handler, the handler will process it and return S_OK. If the preview handler cannot process the keystroke message, it will offer it to the host using TranslateAccelerator. If the host processes the message, this method will return S_OK. If the host does not process the message, this method will return S_FALSE.</returns>
[PreserveSig]
int TranslateAccelerator(MSG pmsg);
};
“`
注:代码来自SharpShell项目
接着,我们可以通过托管代码实现上述接口,并编译成托管dll。
这里需要注意的是,通过.NET框架编译出来的DLL,即使实现了一些COM接口,但它本质上并不是COM组件,但是.NET的运行环境CLR本身却是一个COM组件,名为mscoree.dll。因此,对托管DLL组件注册时应该按照以下规则:
可以看到,被注册的COM组件其实是mscoree.dll,而我们的托管程序只是作为被该组件调用的一个插件。
在注册了该组件之后,照上一篇文章的方法,把文件类型与应用CLSID进行绑定,我们就可以在资源管理器中对文件进行预览了。
另外,如果利用SharpShell库提供的方法,我们不必自己对COM接口进行引入,SharpShell为我们提供了多种Windows Shell接口托管封装,包括DropHandler, IconHandler, IconOverlayHandler,InfoTipHandler,PreviewHandler,PropertySheet以及ContexMenu的封装。使用的方法也很简单,在新建了.NET项目之后可以通过Nuget包对其进行引用,最新版本支持.NET 4.5
另外SharpShell的源码和例程也可以在
http://www.codeproject.com/script/articles/download.aspx?file=/KB/shell/533948/SharpShell_Source_Code.zip&rp=http://www.codeproject.com/Articles/533948/NET-Shell-Extensions-Shell-Preview-Handlers找到
由于SharpShell提供了很好的托管封装,在自定义Windows交互的时候非常推荐大家使用。
- 上一篇: PHP调用另一文件中的类
- 下一篇: CStdioFile按行读取文件.