2008年(909)
分类:
2008-05-06 22:13:07
下载源代码
一、关于普通DLL插件的实现VC知识库里已有文章介绍,但在很多大型的软件中(如ArcGis、Office)中都不是采用这种方法,基于COM的插件在当今的大型软件中应用的更广泛。
二、实现插件离不开三个要素
本文的例子中TestSvr是第一个要素,是插件管理器,plugin目录下的两个工程是第三个要素是插件COM,Interface code目录下的工程是提供基本类的COM,是我们上面提到的第二个要素。
三、在DLL插件中我们搜索插件的方法是将插件存放在与主程序相对固定的目录下,主程序通过搜索目录文件而搜索插件,在COM插件里我们不能用这种方法搜索插件,这里我们采用的方法是每个COM插件都注到一下固定的COM分组中,主程序在COM分组中搜索出插件 。void SpecialReg(GUID ID_SubItem,BOOL bRegister) { ICatRegister* pICatRegister = NULL ; HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatRegister, (void**)&pICatRegister) ; if (FAILED(hr)) { ErrorMessage("Could not create the ComCat component.", hr); return ; } CATEGORYINFO CatInfo ; CatInfo.catid = CATID_MyCategory ; CatInfo.lcid = LOCALE_SYSTEM_DEFAULT ; wcscpy(CatInfo.szDescription,sCateGoryName) ; if (bRegister) { hr = pICatRegister->RegisterCategories(1, &CatInfo) ; hr = pICatRegister->RegisterClassImplCategories(ID_SubItem, 1, &CATID_MyCategory) ; } else { hr = pICatRegister->UnRegisterClassImplCategories(ID_SubItem, 1, &CATID_MyCategory); ICatInformation* pICatInformation = NULL ; hr = pICatRegister->QueryInterface(IID_ICatInformation, (void**)&pICatInformation) ; IEnumCLSID* pIEnumCLSID = NULL ; hr = pICatInformation->EnumClassesOfCategories(1, &CATID_MyCategory, 0, NULL, &pIEnumCLSID) ; CLSID clsid ; hr = pIEnumCLSID->Next(1, &clsid, NULL) ; if (hr == S_FALSE) { hr = pICatRegister->UnRegisterCategories(1, &CATID_MyCategory) ; } pIEnumCLSID->Release() ; pICatInformation->Release() ; } if (pICatRegister) { pICatRegister->Release() ; } }以下的代码是从COM组中列举各个COM组件
ICatInformationPtr pICatInformation(CLSID_StdComponentCategoriesMgr); IEnumCLSID* pIEnumCLSID = NULL ; HRESULT hr = pICatInformation->EnumClassesOfCategories(1, &CATID_RdExcelExportCategory, 0, NULL, &pIEnumCLSID) ; ASSERT(SUCCEEDED(hr)) ; long nComandID = _BASE_COMMAND_ID_; CLSID clsid ; while ((hr = pIEnumCLSID->Next(1, &clsid, NULL)) == S_OK) { RDINTERFACELib::ICommandPtr pCommand(clsid); }下载本文示例代码