例子:编写CyberArticle导入文件插件(Visual C++)建立工程启动Visual Studio,然后点击菜单 File->New->Project
选择Visual C++->ATL->ATL工程
工程名为MyCAImportPlugin1。
新建工程向导中,完全采用默认设置。新建工程后,VS2005会生成工程文件
增加COM组件在工程上面点击右键,选择Add->Class
在添加class对话框里面,选择Visual C++->ATL->ATL Simple Object
在ATL对象向导对话框中,输入COM组件的名称(short name): CAImportPlugin1
然后点击完成。
Visual Studio将会自动生成COM组件对应的class, idl等等。
添加属性和方法切换到Class View
找到ICAImportPlugin1节点,在上面单击鼠标右键,选择Add->Add Property。
将会出现添加属性对话框。
属性类型为LONG类型,属性的名称是PluginFlags。取消Put
function前面的对号(这个属性是只读的,我们不需要Put功能)。然后点击完成按钮。
然后我们按照这个方法,添加ImportFlags属性,属性类型:LONG,注意,我们只需要保留Put function,而不需要Get
function。
然后添加方法。
同样,切换到Class View:
找到ICAImportPlugin1节点,在上面单击鼠标右键,选择Add->Add Property。
将会出现添加方法对话框:
添加下面的方法
方法名:Accept
参数:
然后点击完成按钮。
然后继续添加方法:
方法名:Import
参数:
到这里,必须的属性和方法和都已经添加完毕。
idl文件片段:
interface ICAImportPlugin1 : IDispatch{ [propget, id(1), helpstring("property PluginFlags")] HRESULT PluginFlags([out, retval] LONG* pVal); [propput, id(2), helpstring("property ImportFlags")] HRESULT ImportFlags([in] LONG newVal); [id(3), helpstring("method Accept")] HRESULT Accept([in] BSTR bstrFileName, [out,retval] VARIANT_BOOL* pbAccept); [id(4), helpstring("method Import")] HRESULT Import([in] BSTR bstrFileName, [in] IDispatch* pParentNodeDisp, [out,retval] VARIANT_BOOL* pbSucceeded); }; 注册插件要让CyberArticle知道这个插件,您必须进行注册。
打开MyCAImportPlugin1.cpp并进行修改(斜体部分是增加的内容)。
// MyCAImportPlugin1.cpp : Implementation of DLL Exports. #include "stdafx.h" #include "resource.h" #include "MyCAImportPlugin1.h" /* * 包含必要的头文件。如果CyberArticle没有安装在C:\Program Files\Wizissoft\CyberArticle\,请修改下面相应的包含路径。 */ #include "C:/Program Files/Wizissoft/CyberArticle/developers/interface/include/CyberArticleImportPluginHelper.h" class CMyCAImportPlugin1Module : public CAtlDllModuleT< CMyCAImportPlugin1Module > { public : DECLARE_LIBID(LIBID_MyCAImportPlugin1Lib) DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MYCAIMPORTPLUGIN1, "{9649C428-B6E2-4DA5-B733-16AEB91454AC}") }; CMyCAImportPlugin1Module _AtlModule; #ifdef _MANAGED #pragma managed(push, off) #endif // DLL Entry Point extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { hInstance; return _AtlModule.DllMain(dwReason, lpReserved); } #ifdef _MANAGED #pragma managed(pop) #endif // Used to determine whether the DLL can be unloaded by OLE STDAPI DllCanUnloadNow(void) { return _AtlModule.DllCanUnloadNow(); } // Returns a class factory to create an object of the requested type STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { return _AtlModule.DllGetClassObject(rclsid, riid, ppv); } // DllRegisterServer - Adds entries to the system registry STDAPI DllRegisterServer(void) { // registers object, typelib and all interfaces in typelib HRESULT hr = _AtlModule.DllRegisterServer(); //注册插件 CyberArticleRegisterImportPlugin(CLSID_CAImportPlugin1, _T("导入插件示例,导入图片(*.gif;*.png;*.jpg;*.bmp)")); // return hr; } // DllUnregisterServer - Removes entries from the system registry STDAPI DllUnregisterServer(void) { HRESULT hr = _AtlModule.DllUnregisterServer(); //卸载插件 CyberArticleUnregisterImportPlugin(CLSID_CAImportPlugin1); // return hr; }上面的代码,在注册COM组件的时候,同时使用CyberArticle辅助函数CyberArticleRegisterImportPlugin/CyberArticleUnregisterImportPlugin,向注册表指定位置写入数据,完成插件注册。 完成插件功能到这里,我们已经完成了插件框架的编写。现在编译整个程序,然后打开CyberArticle,从主菜单中选择“文件->导入->导入文件”,打开导入文件对话框。
从文件类型中,已经有我们的插件了:
为了能够成功导入图片,我们必须编写一些代码。
打开CAImportPlugin1.cpp文件(斜体部分是新增内容)
// CAImportPlugin1.cpp : Implementation of CCAImportPlugin1 #include "stdafx.h" #include "CAImportPlugin1.h" #include <atlstr.h> #include "C:/Program Files/Wizissoft/CyberArticle/developers/interface/include/CyberArticleBook.h" #include "C:/Program Files/Wizissoft/CyberArticle/developers/interface/include/CyberArticleBook_i.c" // CCAImportPlugin1 STDMETHODIMP CCAImportPlugin1::get_PluginFlags(LONG* pVal) { // TODO: Add your implementation code here if (!pVal) return E_INVALIDARG; // *pVal = 0; return S_OK; } STDMETHODIMP CCAImportPlugin1::put_ImportFlags(LONG newVal) { // TODO: Add your implementation code here return S_OK; } STDMETHODIMP CCAImportPlugin1::Accept(BSTR bstrFileName, VARIANT_BOOL* pbAccept) { // TODO: Add your implementation code here if (!pbAccept) return E_INVALIDARG; // CString strFileName(bstrFileName); // TCHAR szExt[MAX_PATH] = {0}; // _tsplitpath_s(strFileName, NULL, 0, NULL, 0, NULL, 0, szExt, MAX_PATH); // /* 检查文件扩展名,是否是支持的图片类型。 */ // CString strExt(szExt); strExt.MakeLower(); // BOOL bAccept = (strExt == _T(".jpg") || strExt == _T(".png") || strExt == _T(".gif") || strExt == _T(".tif") || strExt == _T(".bmp") || strExt == _T(".ico")); // /* 通过pbAccept返回是否支持指定的文件。 */ *pbAccept = bAccept ? VARIANT_TRUE : VARIANT_FALSE; // return S_OK; } STDMETHODIMP CCAImportPlugin1::Import(BSTR bstrFileName, IDispatch* pParentNodeDisp, VARIANT_BOOL* pbSucceeded) { // TODO: Add your implementation code here if (!pbSucceeded) return E_INVALIDARG; // *pbSucceeded = VARIANT_FALSE; // CString strFileName(bstrFileName); // if (!PathFileExists(strFileName)) return E_INVALIDARG; // TCHAR szExt[MAX_PATH] = {0}; TCHAR szName[MAX_PATH] = {0}; // _tsplitpath_s(strFileName, NULL, 0, NULL, 0, szName, MAX_PATH, szExt, MAX_PATH); // /* 生成一个简单的HTML文件,文件引用了指定的图片 */ CString strHTML; strHTML.Format(_T("<html><head><title>%s</title></head><body><img src=\"%s\"></img></body></html>"), szName, (LPCTSTR)strFileName); // /* 获得需要导入的图片所在的CyberArticle书籍文件夹 */ CComQIPtr<ICANode, &IID_ICANode> spParentNode(pParentNodeDisp); if (!spParentNode) return E_FAIL; // /* 获得书籍 */ CComPtr<IDispatch> spBookDisp; if (FAILED(spParentNode->get_Book(&spBookDisp))) return E_FAIL; // CComQIPtr<ICABook> spBook(spBookDisp); if (!spBook) return E_FAIL; // /* 在指定的文件夹下面,创建文章。 */ CComPtr<IDispatch> spArticleDisp; HRESULT hr = spBook->CreateArticle(spParentNode, CComBSTR(szName), &spArticleDisp); if (FAILED(hr)) return E_FAIL; // CComQIPtr<ICANode, &IID_ICANode> spArticle(spArticleDisp); if (!spArticle) return E_FAIL; // /* 设置文章的来源 */ spArticle->put_URL(bstrFileName); // /* 获得用于保存文章的配置文件 */ CComPtr<ICAProfileCollection> spProfileCollection; if (FAILED(spProfileCollection.CoCreateInstance(CLSID_CAProfileCollection))) return E_FAIL; // CComPtr<IDispatch> spProfileDisp; if (FAILED(spProfileCollection->get_ProfileForEdit(&spProfileDisp))) return E_FAIL; // CComQIPtr<ICAProfile> spProfile(spProfileDisp); if (!spProfile) return E_FAIL; // /* 利用生成的HTML,初始化文章数据 */ hr = spArticle->InitArticle(CComBSTR(strHTML), bstrFileName, spProfile); if (FAILED(hr)) return E_FAIL; // /* 设置文件类型 */ spArticle->put_FileType(CComBSTR(szExt)); /* 设置节点图标索引 */ spArticle->put_IconIndex(16); // /* 成功导入 */ *pbSucceeded = VARIANT_TRUE; // return S_OK; }重新编译工程,在CyberArticle里面,就可以利用我们的插件,导入图片了。 |
|
|