中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Visual C++ > COM技术
COM插件模型浅谈
作者:未知 时间:2005-07-20 14:21 出处:VC知识库 责编:chinaitpower
              摘要:COM插件模型浅谈

COM插件模型浅谈

作者:杜春辉

下载源代码

一、关于普通DLL插件的实现VC知识库里已有文章介绍,但在很多大型的软件中(如ArcGis、Office)中都不是采用这种方法,基于COM的插件在当今的大型软件中应用的更广泛。

二、实现插件离不开三个要素

  1. 插件管理器(即:要使用这些插件的主程)
  2. 插件基本接口(即:插件与管理器都认可的接口标准),在DLL插件中这个要素通常是一个标准的C++头文件,在COM插件中我们常用一个包含基类的接口COM,在这个COM中它只定义接口,不作任何实现。
  3. 插件COM,在这些COM中,它们只实现基类COM库的接口,没有自己的接口。

  本文的例子中TestSvr是第一个要素,是插件管理器,plugin目录下的两个工程是第三个要素是插件COM,Interface code目录下的工程是提供基本类的COM,是我们上面提到的第二个要素。

三、在DLL插件中我们搜索插件的方法是将插件存放在与主程序相对固定的目录下,主程序通过搜索目录文件而搜索插件,在COM插件里我们不能用这种方法搜索插件,这里我们采用的方法是每个COM插件都注到一下固定的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);
}      
关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有