引子
首先,什么是Preview和Thumbnail?
简单理解,Windows下Preview就是预览,Thumbnail就是缩略图。
一图以蔽之。
其次,如何开发自己格式文件的Preview、Thumbnail?
使用Windows Shell中的IPreviewHandler、IThumbnailProvider
微软官方示例
- Windows Shell preview handler(CppShellExtPreviewHandler)
https://code.msdn.microsoft.com/CppShellExtPreviewHandler-58db53b8
- Windows Shell thumbnail handler(CppShellExtThumbnailHandler)
https://code.msdn.microsoft.com/CppShellExtThumbnailHandler-32399b35
Preview
Preview开发主要步骤:
- 新建RobotArtExtPreviewHandler工程
- 加入Art自己的处理逻辑(读取相关信息)
- 编译出dll
- 安装包将dll打包至指定目录,并注册
1、新建Win32 dll Empty项目
2、借鉴官方示例,添加dll注册处理模块
- Shell extension handlers are COM objects implemented as DLLs.官方说明preview的shell扩展是一个作为dll实现的com对象。需要为其指定一个CLSID。
// {E46116A3-24EF-4525-8131-96C4E74F6FBE} const CLSID CLSID_RobotArtPreviewHandler = { 0xe46116a3, 0x24ef, 0x4525, { 0x81, 0x31, 0x96, 0xc4, 0xe7, 0x4f, 0x6f, 0xbe } };
讯享网
注:IPreviewHandler的GUID为8895b1c6-b41f-4c1c-a562-0df,所有自定义开发的preview组件均需挂在其下。
讯享网 // Remove the registry key: // HKCR\<File Type>\shellex\{8895b1c6-b41f-4c1c-a562-0df} hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"%s\\shellex\\{8895b1c6-b41f-4c1c-a562-0df}", pszFileType); if (SUCCEEDED(hr)) { hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, szSubkey)); }
可以参考word文档.doc在注册表中的数据,如下图所示。

- DllRegisterServer函数中绑定自定义格式文件与新建组件
// Register the component. hr = RegisterInprocServer(szModule, CLSID_RobotArtPreviewHandler, L"RobotArtExtPreviewHandler.RobotArtPreviewHandler Class", L"Apartment", APPID_RobotArtPreviewHandler); if (SUCCEEDED(hr)) { // Register the preview handler. The preview handler is associated // with the .recipe file class. hr = RegisterShellExtPreviewHandler(L".robx", CLSID_RobotArtPreviewHandler, L"RobotArtPreviewHandler"); }
3、创建COM类,实现IPreviewHandler相关接口
讯享网class RobotArtPreviewHandler : //public IInitializeWithStream, public IInitializeWithFile, public IPreviewHandler, public IPreviewHandlerVisuals, public IOleWindow, public IObjectWithSite
注意这里面继承的接口,
IInitializeWithStream 重载函数获得文件流
// IInitializeWithStream IFACEMETHODIMP Initialize(IStream *pStream, DWORD grfMode);
对于较小的或者xml格式的自定义文件,可以采取文件流方式;微软官方的示例就是重载的IInitializeWithStream。
IInitializeWithFile 重载函数获得文件路径
讯享网// IInitializeWithFile IFACEMETHODIMP Initialize(LPCWSTR pfilePath, DWORD grfMode);
这种方式,拿到的是文件路径,后续可以用自己的方式去解析文件。
IPreviewHandler 主要用到DoPreview,在其中实现自定义文件解析及PreviewWindow(就是资源管理器中右边预览窗格中你看到的)的Create 。
// IPreviewHandler IFACEMETHODIMP SetWindow(HWND hwnd, const RECT *prc); IFACEMETHODIMP SetFocus(); IFACEMETHODIMP QueryFocus(HWND *phwnd); IFACEMETHODIMP TranslateAccelerator(MSG *pmsg); IFACEMETHODIMP SetRect(const RECT *prc); IFACEMETHODIMP DoPreview(); IFACEMETHODIMP Unload();
4、添加对话框资源,用来显示预览图片以及你想要显示的自定义信息。


这里需要注意一点是,如果你需要在预览窗口里进行单击操作之类,比如单击操作者就跳转到他的主页的话,就需要在DoPreview中CreateDialog时一定要注意为其指定回调函数,否则对话框内的消息com组件中响应不到。
讯享网INT_PTR CALLBACK DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam); //HWND m_hwndPreview;头文件中定义的 m_hwndPreview = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_MAINDIALOG), m_hwndParent, (DLGPROC)DlgProc); INT_PTR CALLBACK DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch(msg) { case WM_SYSCOMMAND: if(wParam == SC_CLOSE) { // 如果执行了关闭 // 销毁对话框,将收到WM_DESTROY消息 DestroyWindow(hdlg); } return 0; /*case WM_COMMAND: { if(LOWORD(wParam) == IDC_BUTTON_CREATOR) { } } return 0;*/ case WM_NOTIFY: { PNMLINK pNmlink = (PNMLINK)lParam; if(pNmlink->hdr.code == NM_CLICK) { if((LOWORD(wParam) == IDC_SYSLINK_CREATOR) || (LOWORD(wParam) == IDC_SYSLINK_EDITOR)) { { HINSTANCE result = ShellExecute(NULL, _T("runas"), _T("iexplore.exe"), _T("http://www.robotart.com/WorksWall/Index"), NULL, SW_SHOWNORMAL); } } } } return 0; } return (INT_PTR)FALSE; }
还需要注意一点是在点击创建者Syslink响应中需要注意,shell扩展的用户权限可能不是很高,上述代码中ShellExecute启动浏览器未必会成功,需要加上runas予以提权。
5、注册与卸载
Regsvr32.exe CppShellExtThumbnailHandler.dll Regsvr32.exe /u CppShellExtThumbnailHandler.dll
Thumbnail
Thumbnail开发主要步骤:
- 新建RobotArtThumbnailHandler 工程
- 加入Art自己的处理逻辑
- 编译出dll
- 安装包将dll打包至指定目录,并注册
主要步骤与Preview大致相同,也需要新建Win32 dll Empty项目、添加dll注册处理模块 ,只不过是实现的接口不一样而已。
讯享网class RobotArtThumbnailHandler : //public IInitializeWithStream, public IInitializeWithFile, public IThumbnailProvider
// IThumbnailProvider IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha);
注:IThumbnailProvider的GUID为e357fccd-a995-4576-b01f-e96,所有自定义开发的thumbnail组件均需挂在其下。

有关Preview、Thumbnail中图片的处理
Preview、Thumbnail中都需要用到图像,如果每次都将图片解到磁盘后再用势必不如将图片解到内存中快捷安全。所以在DocMeta Cfg中存了缩略图的base64字符串,shell扩展程序中使用时再由base64字符串转为img。你可以考虑在你的文件格式中将图片存成base64字符串。
有关Preview、Thumbnail的调试
Preview调试,attach prevhost进程即可。
Thumbnail调试,暂不知。thumbnail的调用进程在explore.exe中,不知道该attach谁。
敲重点:
一定要看官方示例,微软的例子写的很清楚明白。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/23298.html