ATL开发指南的第三章的讲述的重点有四个:

   1.ATL如何提供对组件宿主的支持。

   2.ATL如何提供对IUnknown接口实现的支持。

    3.ATL如何提供对类工厂的支持。

    4.ATL如何提供对组件自注册的支持。


3.1 ATL 的基本特征




描述:ATL提供了实现基于COM组件内核的支持.下面是ATL所提供的一些功能

1.AppWizard,它负责创建起始的ATL工程
2.Object Wizard(对象向导),它为基本的COM组件创建代码
3.对低级别的COM功能的内置式支持,如IUnknown,类工厂和自注册
  (self-registration)功能
4.ATL支持Microsoft的接口定义语言(Interface Definition Language,IDL),它提供
  了对自定义的Vtable接口的调度支持,以及通过类型库进行自描述的功能
5.ATL支持IDispatch(自动化)和双向接口(dual-interface)
6.ATL可以支持开发效率更高的ActiveX控件
7.ATL提供对基本的视窗功能的支持

3.2 ATL 和 MFC




描述:ATL的目标是为了简化小规模的,基于COM组件的创建.MFC则基于Windows应用程序的开发速度,它通常带有大量的GUI.两者的相似之处是对OLE和ActiveX的支持

3.3 ATL 框架结构概述

描述:ATL是一个C++的类库或框架,它处理基于COM程序开发中的很多琐碎的例行工作,如,COM组件需要一个DLL或EXE宿主,而组件也需要一个类工厂.

3.3.1 ATL 的实现




1)ATL是一个基于模板的框架,它将ATL的实现作为你组件实现里的一部分.因此,你只需要在程序里包含头文件,即可获得ATL内建的功能.

2)ATL的设计目标是为了建立小型的,独立的组件.ATL提供了几个选项处理可执行文件变大的问题.如:

// stdafx.h
#define _ATL_APARTMENT_THREADED
#include <atlbase.h>
#include <atlcom.h>
....

// stdafx.cpp
#include "stdafx.h"

// include ATL's implementation code
#include <atlimpl.cpp>

// Yourimplementation.cpp
#include "stdafx.h"

stdafx文件包含了工程类型的基本要求,所以需要把它包含在你的实现文件里,通过ATLIMPL.CPP大部分ATL的实现都成为工程的一个显示部分,它的代码也变成你的可执行文件的一部分

ATL 的实现文件

文件名称



说明



ATLBASE.H


ATL工程的基本包含文件


ATLCOM.H


所有的ATL工程都必须包含ATLCOM.H,因为该文件提供了ATL的大部分基本行为


ATLIMPL.CPP


在ATLBASE.H和ATLCOM.H里声明的类和方法的实现代码


ATLCTL.H,ATLCTL.CPP


ATL对ActiveX控件所提供的支持,若使用ATL的控件支持,应包含它们


ATLWIN.H,ATLWIN.CPP


ATL对视窗和对话框的支持


STATREG.H,STATREG.CPP


ATL的注册组件的实现文件


ATLIFace.IDL,ATLIFACE.H


ATL的注册器组件的支持文件,头文件里包含了输出,该输出是通过MIDL编译器运行IDL的结果



 

3)ATL实现一些基本的API是在一个名为ATL.DLL的模块里进行的.它提供ATL类的辅助函数.

4)如果定义了ATL_DLL_符号变量,工程将依赖于ATL.DLL文件.若没有,ATLIMPL.CPP文件将把实现作为模块的一部分包含进来

3.3.2 组件的宿主支持




ATL在它的CComModule类里封装了一个组件的宿主支持.ATL对开发者掩盖了这两种宿主类型(dll或exe)之间的大多数差别.

3.3.3 对IUnknown的支持

在下面为详细讲述.

3.3.4 对类工厂的支持

1)CComClassFactory提供了对基本的类工厂的支持

2)CComClassFactory2对获得许可的类工厂提供支持

3)CComClassFactorySingleton为单元素类工厂提供支持





3.3.5 对COM程序开发的其他方面的支持

COM的功能项



ATL的支持类



ActiveX控件


CComControl,IOleControlImpl,IOleObjectImpl 等都支持控件开发


自动化(Automation)


IDispatchImpl处理自动化和双向接口


COM的数据类型


CComVariant


接口指针的管理


CComPtr 和 CComQIPtr


错误处理


ISupportErrorInfoImpl 和CComObject


连接点(Connection points)


IConnectionPointContainerImpl 和 IConnectionPointImpl


异步属性下载


CBindStatusCallback


自注册(self-registration)


ATL的注册对象(Register object,Iregistrar)提供自注册功能


视窗和对话框


CWindow,CWindowImpl,CDialogImpl,CMessageMap



 

3.4.3 线程管理模型




Apartment:     组件的实例可以存在于它们自身的单元(Apartment)线程。

Free:              组件支持自由线程管理模型里(Free Threading Model)。换句话说,它必须和其它线程一起位于多线程单元(Multithread Apartment 或 MTA)里。

Both:          它指定组件既可以支持单元模型,也可以支持自由线程模型。

3.8.4 Atl 对组件的支持




1)每一个COM对象都必须支持IUnknown接口和其他公开其特定功能的接口

2)每一个COM对象也必须提供一个类工厂,从而客户应用程序才可以创建它

3)COM对象应该提供自注册功能

3.8.4.1 ATL对IUnknown的支持




1) 每一个将成为COM对象的ATL类都必须从CComObjectRootEx类里派生出来.

2)CComObjectRootEx间接地为组件提供了引用计数和QueryInterface支持

3) CComObjectRootEx 从CComObjectRootBase继承,CComObjectRootBase对组件里的基本集合提供支持,而CComObjectRootEx对非集合的IUnknown方法提供支持。

3.8.5 AddRef 和 Release所在的位置




1)ATL通过CComObjectRootEx的内部和外部方法来管理引用的计数,CComObject中的类则处理对IUnknown方法实现

2)生成CMath类实例IMath *pIMath = new CComObject<CMath>

3)实现math组件所必须的继承图

abbet标准 适合开发ats架构 atl开发指南_abbet标准 适合开发ats架构

1.CComObjectRoot提供InternalAddRef,InternalRelease,InternalQueryInterface

2.CComCoClass 提供了对类工厂的支持

3.IMath,IAdvancedMath 提供了抽象的接口类

4.以上这些组合在一起生成了CMath类,ATL更深一步,为了创建实例,它使用CMath作为CComObject的模板参数,使CComObject从CMath中派生出来,为组件的IUnknown接口提供实现。




3.8.6 CComObject




CComObject类直接调用了由CComObjectRootEx 实现的内部方法(如InternalAddRef),所以不能支持集合。

在ATL里,你可以使用几个类似于CComObject 的类来创建真正的、可实例化的类。

类名称



说明



CComObject


在大多数典型的COM组件里使用。该对象不支持集合,也不能处理引用计数,而通常的对象则可以支持集合及处理引用计数。当引用计数器减小到零时,它就把自己删除掉。


CComObjectNoLock


类似于CComObject,不过该对象的生存期不会影响组件宿主文件的锁定计数,ATL在它的宿主类工厂的实现里使用了该类,这是因为宿主类工厂的生存期不应该影响宿主的生存期


CComAggObject


它仅仅支持集合。IUnKnown的实现通过外部组件来实现。


CComContainedObject


因为它把所有的调用都委托给外部对象(或父级对象),所以它类似于一个集合对象。然而,当该类被包含到你的实现里时(换句话说,也就是当你不进行显式的集合操作时),你可以使用该类(个人认为可以理解为“包容”)。


CComPolyObject


它支持集合或标准实现。该类基本上是一个占位实现。


CComObjectStack


该实现完全不支持引用计数。它是结合堆栈所创建的COM对象一起使用的。堆栈所创建的COM对象的生存期有一定限制,这一点不难理解。


CComObjectGlobal


CComObjectGlobal的生存期和组件宿主文件的生存期相同。换句话说,它完全类似于一个全局的C++对象。它的生存期是宿主的全局锁定计数器决定的。


CComObjectCached


一旦创建了该类的对象,它就会存储在对象的缓存里。ATL使用它来实现一个组件的类工厂。


CComTearOffObject


Tear-off对象提供了一种只在需要时创建类的机制。



 





3.8.10 自注册与注册器功能




注册器(Registrar)是一个简单的、数据驱动的机制,它使用宿主文件组件的信息来刷新注册表。它定义了IRegistrar接口,Registrar 组件的实现由STATREG.H 和 STAREG.CPP提供。

在组件的头文件中使用DECLARE_REGISTRY_RESOURCEID()宏来注册组件。DECLARE_REGISTRY_RESOURCEID宏使用包含RGS文件的资源ID做为参数,使用RGS的内容进行注册。