WEB开发网
开发学院软件开发VC 编写可复用性更好的C++代码:Band对象和COMToys(2)... 阅读

编写可复用性更好的C++代码:Band对象和COMToys(2)

 2006-07-21 11:44:10 来源:WEB开发网   
核心提示: // 例子中把脚本都放在了应用程序的资源中MyBands.rcIDR_INFOBAND REGISTRY DISCARDABLE "BandObj.rgs"IDR_COMMBAND REGISTRY DISCARDABLE "BandObj.rgs"
// 例子中把脚本都放在了应用程序的资源中MyBands.rc
IDR_INFOBAND REGISTRY DISCARDABLE "BandObj.rgs"
IDR_COMMBAND REGISTRY DISCARDABLE "BandObj.rgs"
IDR_DESKBAND REGISTRY DISCARDABLE "BandObj.rgs"   

不过,三个不同的COM对象怎么可能使用相同的注册脚本呢?它们不是有不同的名字和类IDs吗? 这就是IRegistrar的好处之所在。看一下注册脚本BandObj.rgs。到处是%CLSID%, %ClassName%, 和 %MODULE% ,这些标志是什么意思呢? 这些都是变量。在处理脚本之前,注册器会用实际的值(类ID,类名和模块名)替代这些变量。那它怎么知道使用什么值呢?因为你告诉它了--或者说是BandObj告诉它了。你可能注意到了在UpdateRegistry中有一个对OnInitRegistryVariables的调用。就是在这个地方,BandObj定义了它的变量。

BOOL CBandObjFactory::OnInitRegistryVariables(IRegistrar* pReg)
{
   USES_CONVERSION;
   pReg->AddReplacement(OLESTR("CLSID"), StringFromCLSID(m_clsid));
   pReg->AddReplacement(OLESTR("MODULE"), T2OLE(GetModuleName()));
   pReg->AddReplacement(OLESTR("ClassName"), T2OLE(GetClassName()));
   return TRUE;
}   

下面是我在CBandObjFactory中建立的全部变量列表,它们都自动由BandObj定义。

%CLSID%   = class ID (GUID)(COleObjectFactory::m_clsid)
%MODULE%  = DLL的全路径名
%Title%   = 标题(资源子串 0)
%ClassName% = 人可读的COM类名 (资源子串 1)
%ProgID%  = ProgID (资源子串 2)

要想添加自己的变量,如%TimeStamp% 或者 %MyReleaseVersion%,,只要派生一个新类厂并重载OnInitRegistryVariables就可以了。不要忘了调用基类,因为MFC为每一个类厂调用UpdateRegistry,而对每个类而言,变量都被重新初始化。所以在MyBands中,第一个类厂的%CLSID% 是 CLSID_MYINFOBAND,第二个类厂的%CLSID% 是 CLSID_ MYCOMMBAND,而第三个类厂的%CLSID% 是 CLSID_MYDESKBAND。同一个脚本处理三种对象的注册,酷毙了!。

IRegistrar这么酷,所以我写了自己的命令行实用程序 RGSRUN来加载RGS文件,它对于测试和调试脚本或者从注册表种删除多余的垃圾都非常有用,有些功能是REGEDIT所没有的。这个实用程序与本文的例子一起提供。我在autoexec.bat文件中使用RGSRUN加载一个文件:autoexec.rgs,其中设置了不同的Explorer选项,Windows每次启动都会自动完成加载。

种类注册

如果你仔细阅读本文,就会注意到前面提到的脚本文件中没有关于band对象种类注册的内容。为什么呢?BandObj在哪里注册它的种类信息呢?我用了另外一个变量来做这件事情,它就是%catid%,而COM库中也总是有接口应用于此,种类也不例外。正式的种类注册方法是通过ICatRegister实现的:

BOOL CBandObjFactory::UpdateRegistry(BOOL bReg)
{
  ......
  // 使用ICatRegister 注册/注销种类
  CTCatRegister iCat;
  REFIID clsid = m_clsid;
  hr = bRegister ?
   iCat->RegisterClassImplCategories(clsid, 1,      &m_catid) :
   iCat->UnRegisterClassImplCategories(clsid, 1,      &m_catid);
   // 返回,旁路掉MFC
   return hr==S_OK;
}  

由此可见,使用ATL智能指针,COMToys类以及CTCatRegister使编程更轻松。你只要声明实例就行了。(待续)

上一页  1 2 3 4 5 

Tags:编写 复用 更好

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接