例子:编写一个CyberArticle普通插件 (Visual C++)下面是一个用Visual Studio 2005 (Visual C++)开发一个简单的CyberArticle 普通插件的过程。
建立工程启动Visual Studio,然后点击菜单 File->New->Project
选择Visual C++->ATL->ATL工程
工程名为MyCANormalPlugin1。
新建工程向导中,完全采用默认设置。新建工程后,VS2005会生成工程文件
增加COM组件在工程上面点击右键,选择Add->Class
选择Visual C++->ATL->ATL Simple Object
在ATL对象向导对话框中,输入COM组件的名称(short name): CANormalPlugin1
然后点击完成。
Visual Studio将会自动生成COM组件对应的class, idl等等。
找到并修改CANormalPlugin1.h文件这是COM组件class定义文件。斜体部分为增加的内容:
// CANormalPlugin1.h : Declaration of the CCANormalPlugin1 #pragma once #include "resource.h" // main symbols #include "MyCANormalPlugin1.h" /* * 包含必要的头文件。如果CyberArticle没有安装在C:\Program Files\Wizissoft\CyberArticle\,请修改下面相应的包含路径。 */ #include <commctrl.h> #include <exdisp.h> #include "C:/Program Files/Wizissoft/CyberArticle/developers/interface/include/cyberarticleplugininterface.h" #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms." #endif // CCANormalPlugin1 class ATL_NO_VTABLE CCANormalPlugin1 : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CCANormalPlugin1, &CLSID_CANormalPlugin1>, public IDispatchImpl<ICANormalPlugin1, &IID_ICANormalPlugin1, &LIBID_MyCANormalPlugin1Lib, /*wMajor =*/ 1, /*wMinor =*/ 0> , public ICAPlugin //增加实现的接口 { public: CCANormalPlugin1() { } DECLARE_REGISTRY_RESOURCEID(IDR_CANORMALPLUGIN1) BEGIN_COM_MAP(CCANormalPlugin1) COM_INTERFACE_ENTRY(ICANormalPlugin1) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY_IID(IID_ICAPlugin, ICAPlugin) //增加接口 END_COM_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } public: //实现接口ICAPlugin private: CComPtr<ICAApp> m_spApp; public: virtual HRESULT STDMETHODCALLTYPE Init(ICAApp* pApp); virtual HRESULT STDMETHODCALLTYPE Exit(); virtual HRESULT STDMETHODCALLTYPE get_Flags(long* pnFlags); virtual HRESULT STDMETHODCALLTYPE put_Flags(long nFlags); virtual HRESULT STDMETHODCALLTYPE get_MenuItemText(BSTR* pbstrDescription); virtual HRESULT STDMETHODCALLTYPE get_MenuItemStatus(long* pnStatus); virtual HRESULT STDMETHODCALLTYPE get_MenuItemOrder(long* pnMenuItemOrder); virtual HRESULT STDMETHODCALLTYPE Execute(); }; OBJECT_ENTRY_AUTO(__uuidof(CANormalPlugin1), CCANormalPlugin1) 找到并修改CANormalPlugin1.cpp文件这是COM组件实现文件。(斜体部分为增加的内容) // CANormalPlugin1.cpp : Implementation of CCANormalPlugin1 #include "stdafx.h" #include "CANormalPlugin1.h" /* * 包含必要的头文件。如果CyberArticle没有安装在C:\Program Files\Wizissoft\CyberArticle\,请修改下面相应的包含路径。 */ #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" // CCANormalPlugin1 HRESULT STDMETHODCALLTYPE CCANormalPlugin1::Init(ICAApp* pApp) { /* 插件初始化,在CyberArticle启动的时候,会调用这个方法。 */ m_spApp = pApp; ATLASSERT(m_spApp); // return S_OK; } HRESULT STDMETHODCALLTYPE CCANormalPlugin1::Exit() { /* 在CyberArticle退出的时候,会调用这个方法。 */ m_spApp = NULL; // return S_OK; } HRESULT STDMETHODCALLTYPE CCANormalPlugin1::get_Flags(long* pnFlags) { if (!pnFlags) return E_INVALIDARG; // /* 获得插件信息。 CAPLUGIN_FLAG_TYPE_NODES_TOOL:这是一个用来处理节点的插件 CAPLUGIN_FLAG_MENU_BEGIN_GROUP:告诉CyberArticle,在插件菜单前面,先是一个分割线,用来和其它的菜单分开。 */ *pnFlags = CAPLUGIN_FLAG_TYPE_NODES_TOOL | CAPLUGIN_FLAG_MENU_BEGIN_GROUP; // return S_OK; } HRESULT STDMETHODCALLTYPE CCANormalPlugin1::put_Flags(long nFlags) { return S_OK; } HRESULT STDMETHODCALLTYPE CCANormalPlugin1::get_MenuItemText(BSTR* pbstrDescription) { if (!pbstrDescription) return E_INVALIDARG; // /* 返回菜单文字 */ CString strDescription = _T("My CA Normal Plugin"); // *pbstrDescription = strDescription.AllocSysString(); // return S_OK; } HRESULT STDMETHODCALLTYPE CCANormalPlugin1::get_MenuItemStatus(long* pnStatus) { /* 用来更新菜单状态。 */ if (!pnStatus) return E_INVALIDARG; // *pnStatus = 0; // ATLASSERT(m_spApp); // CComPtr<ICAWindow> spWindow; if (FAILED(m_spApp->get_Window(&spWindow))) return S_OK; // long nCount = 0; if (S_OK != spWindow->get_SelectedNodesCount(&nCount) || 0 == nCount) { /* 如果在CyberArticle里面,没有选中任何节点,则让菜单实效 */ *pnStatus = CAPLUGIN_MIS_DISABLED; return S_OK; } // return S_OK; } HRESULT STDMETHODCALLTYPE CCANormalPlugin1::get_MenuItemOrder(long* pnMenuItemOrder) { /* 返回菜单显示顺序 */ ATLASSERT(pnMenuItemOrder); *pnMenuItemOrder = 1000; // return S_OK; } HRESULT STDMETHODCALLTYPE CCANormalPlugin1::Execute() { ATLASSERT(m_spApp); // /* 获得CyberArticle窗口 */ CComPtr<ICAWindow> spWindow; if (FAILED(m_spApp->get_Window(&spWindow))) return E_FAIL; // /* 获得CyberArticle窗口句柄 */ HWND hwndCyberArticle = NULL; spWindow->get_HWND(&hwndCyberArticle); // /* 获得CyberArticle选中的节点 */ CComPtr<ICANodeCollection> spNodeCollection; if (FAILED(spWindow->get_SelectedNodes(&spNodeCollection))) return E_FAIL; // /* 获得CyberArticle选中的节点数量 */ long nCount = 0; spNodeCollection->get_Count(&nCount); // for (long i = 0; i < nCount; i++) { /* 获得每一个选中的节点 */ CComPtr<IDispatch> spDispNode = NULL; if (FAILED(spNodeCollection->get_Item(i, &spDispNode))) continue; // CComQIPtr<ICANode> spNode(spDispNode); if (spNode) { /* 获得节点的标题 */ CComBSTR bstrTitle; if (SUCCEEDED(spNode->get_Title(&bstrTitle)) && bstrTitle) { /* 调用MessageBox对话框,显示节点标题 */ MessageBox(hwndCyberArticle, CString(bstrTitle), _T("My CA Normal Plugin"), MB_OK | MB_ICONINFORMATION); } } } return S_OK; } 找到并修改MyCANormalPlugin1.cpp这个文件主要用来注册COM组件(斜体部分为增加的内容)// MyCANormalPlugin1.cpp : Implementation of DLL Exports. #include "stdafx.h" #include "resource.h" #include "MyCANormalPlugin1.h" /* * 包含必要的头文件。如果CyberArticle没有安装在C:\Program Files\Wizissoft\CyberArticle\,请修改下面相应的包含路径。 */ #include "C:/Program Files/Wizissoft/CyberArticle/developers/interface/include/CyberArticlePluginHelper.h" class CMyCANormalPlugin1Module : public CAtlDllModuleT< CMyCANormalPlugin1Module > { public : DECLARE_LIBID(LIBID_MyCANormalPlugin1Lib) DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MYCANORMALPLUGIN1, "{D1AF3660-89D7-4EBC-9549-50C4F6B8A1D7}") }; CMyCANormalPlugin1Module _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(); // /* 注册CyberArticle插件 */ CyberArticleRegisterPlugin(CLSID_CANormalPlugin1, _T("My CA Normal Plugin1")); // return hr; } // DllUnregisterServer - Removes entries from the system registry STDAPI DllUnregisterServer(void) { HRESULT hr = _AtlModule.DllUnregisterServer(); // /* 取消注册CyberArticle插件 */ CyberArticleUnregisterPlugin(CLSID_CANormalPlugin1); // return hr; } 编译并测试插件然后编译整个工程。如果出现错误,请检查相应的代码。重新运行CyberArticle,选中一个获这多个节点,然后再选中的节点上面,点击右键,再出现的菜单中,将会有我们的插件菜单;点击这个菜单,将会出现消息对话框,上面显示了我们选中的节点的标题。调试插件:在Visual Studio里面,将CyberArticle.exe设置为调试程序,就可以调试插件了。启动CyberArticle,就可以调试插件了。 |
|
|