ATL(Active Template Library)是一组小巧、高效、灵活的类,这些类为创建可互操作的COM组件提供了基本的设施。本书由一流的专家撰写,深入地剖析了ATL中模板类的结构、ATL如何实现COM的各种功能,并且也向您展示了ATL中大量的技巧,同时还指出了当前的ATL中存在的一些错误和缺陷。本书是ATL程序员的权威参考书。\r\n\r\n 本书适合有经验的软件开发人员阅读,也可供其他有兴趣的读者参考。\r\n
\r\n
译序 \r\n\r\n ATL之深入解析 \r\n\r\n 英文版原序 \r\n\r\n 前言 \r\n\r\n 第1章 你好, ATL \r\n\r\n 1. 1 什么是ATL? \r\n\r\n 1. 2 创建COM服务器 \r\n\r\n 1. 3 插入一个COM类 \r\n\r\n 1. 4 加入属性和方法 \r\n\r\n 1. 5 实现其他接口 \r\n\r\n 1. 6 支持脚本 \r\n\r\n 1. 7 添加永久性 \r\n\r\n 1. 8 添加和激发事件 \r\n\r\n 1. 9 使用窗口 \r\n\r\n 1. 10 实现组件类别 \r\n\r\n 1. 11 添加用户界面 \r\n\r\n 1. 12 容纳控制 \r\n\r\n 1. 13 总结 \r\n\r\n 第2章 ATL智能类型 \r\n\r\n 2. 1 字符串数据类型. 转换宏和辅助函数 \r\n\r\n 2. 2 COM字符串数据类型——BSTR \r\n\r\n 2. 3 CComBSTR类 \r\n\r\n 2. 4 智能VARIANT类ComVariant \r\n\r\n 2. 5 CComPtr. CComQIPtr和CComDispatchDriver智能指针类 \r\n\r\n 2. 6 总结 \r\n\r\n 第3章 ATL中的对象 \r\n\r\n 3. 1 回顾COM套间 \r\n\r\n 3. 2 ATL的层次 \r\n\r\n 3. 3 线程模型支持 \r\n\r\n 3. 4 IUnknown的核心 \r\n\r\n 3. 5 我们的类 \r\n\r\n 3. 6 CComObject及其他 \r\n\r\n 3. 7 ATL创建者 \r\n\r\n 3. 8 调试 \r\n\r\n 3. 9 总结 \r\n\r\n 第4章 CoM服务器 \r\n\r\n 4. 1 回顾COM服务器 \r\n\r\n 4. 2 对象映射表和CComModule类 \r\n\r\n 4. 3 对象映射表 \r\n\r\n 4. 4 对象映射类要求的方法 \r\n\r\n 4. 5 CComModule类 \r\n\r\n 4. 6 重游CComCoClass \r\n\r\n 4. 7 服务器优化编译选项 \r\n\r\n 4. 8 总结 \r\n\r\n 第5章 接口映射表 \r\n\r\n 5. 1 回顾:COM的实体身份 \r\n\r\n 5. 2 表驱动的QueryInterface \r\n\r\n 5. 3 多重继承 \r\n\r\n 5. 4 tear—off接口 \r\n\r\n 5. 5 聚合:外部控制对象 \r\n\r\n 5. 6 接口映射表的技巧 \r\n\r\n 5. 7 总结 \r\n\r\n 第6章 ATL中的永久性 \r\n\r\n 6. 1 回顾COM的永久性 \r\n\r\n 6. 2 ATL永久实现类 \r\n\r\n 6. 3 属性映射表 \r\n\r\n 6. 4 永久实现 \r\n\r\n 6. 5 其他永久实现 \r\n\r\n 6. 6 使用永久功能加入“按值列集”的语义 \r\n\r\n 6. 7 总结 \r\n\r\n 第7章 集合和枚举器 \r\n\r\n 7. 1 COM集合和枚举接口 \r\n\r\n 7. 2 枚举数组 \r\n\r\n 7. 3 枚举STL集合 \r\n\r\n 7. 4 集合 \r\n\r\n 7. 5 ATL数据类型的STL集合 \r\n\r\n 7. 6 简单集合 \r\n\r\n 7. 7 对象模型 \r\n\r\n 7. 1 总结 \r\n\r\n 第8章 连接点 \r\n\r\n 8. 1 回顾连接点 \r\n\r\n 8. 2 创建基于ATL的可连接对象 \r\n\r\n 8. 3 创建一个接收事件的对象 \r\n\r\n 8. 4 这一切是如何工作的:零散的实现细节 \r\n\r\n 8. 5 总结 \r\n\r\n 第9章 窗口 \r\n\r\n 9. 1 Windows应用程序的结构 \r\n\r\n 9. 2 CWindow \r\n\r\n 9. 3 CWindowImpl \r\n\r\n 9. 4 CDialogImpl \r\n\r\n 9. 5 Windows控制包装类 \r\n\r\n 9. 6 CContainedWindow \r\n\r\n 9. 7 总结 \r\n\r\n 第10章 ActiveX控制 \r\n\r\n 10. 1 回顾ActiveX控制 \r\n\r\n 10. 2 BullsEye控制的需求 \r\n\r\n 10. 3 利用ATL向导创建初始的控制 \r\n\r\n 10. 4 初始的BullsEye源文件 \r\n\r\n 10. 5 循序渐进地开发BullsEye控制 \r\n\r\n 10. 6 总结 \r\n\r\n 第11章 控制包容 \r\n\r\n 11. 1 控制是如何被包含的 \r\n\r\n 11. 2 基本的控制容器 \r\n\r\n 11. 3 在对话框中容纳一个控制 \r\n\r\n 11. 4 复合控制 \r\n\r\n 11. 5 HTML控制 \r\n\r\n 11. 6 ATL控制包容的局限 \r\n\r\n 11. 7 总结 \r\n\r\n 附录A 用例子解析C++模板 \r\n\r\n A. 1 对模板的需求 \r\n\r\n A. 2 模板基础 \r\n\r\n A. 3 另一种多态性 \r\n\r\n A. 4 函数模板 \r\n\r\n A. 5 成员函数模板 \r\n\r\n A. 6 总结 \r\n\r\n 附录B ATL类和头文件 \r\n
\r\n
一年前我第一次看到这本书的英文版, 拜读之后, 我知道这是一本重量级的技术书籍. 去年5月份曾经为这本书写过一篇长长的介绍(有一万多字), 也曾拜托朋友在有关的电脑杂志上发表我的书评, 竟然无人敢接. 似乎高阶技术在国内总是不被看好, 倒是初阶技术的资料大行其道, 浪费和重复自不必说, 问题是高阶技术也有广阔的市场, 为什么商家就看不到呢?我这么说是有根据的, 因为当我把书评放到Internet上之后, 不断有朋友来问讯这本书的出版消息, 很多读者希望看到这样的书. 幸运的是, 中国电力出版社引进了这本书, 而我也有机会为大家翻译这本书, 并再一次向读者作介绍.
ATL是专门用于开发COM组件的模板库, 当前的最新版本是ATL3. 0(随Visual C++6. 0发布), 尽管它已经有将近5年的历史了, 但是在国内ATL并没有被普及开来, 我想原因有多个方面. 第一, ATL涉及到的技术比较复杂, 首先它是用来开发COM组件的, 而COM本身比较偏于底层, 从而导致ATL的背景要复杂得多, 其次ATL是建立在C++的模板(template)语法基础上的, 所以要想掌握ATL, 必须具备比较好的C++基础, 而这一点并不是很容易就能做到的. 第二, ATL的参考资料很少, 虽然ATL的源码是完全开放的, 但是源码背后隐藏着许多概念和思想, 这些概念和思想并不是直接体现出来的, 好的资料来源可以帮助我们抓住这些要点, 并用好ATL. 毫无疑问, 本书是最好的ATL参考资料.
本书不是一本讲述如何使用ATL的向导指南, 它并不是简单地教你如何利用ATL中的模板类实现COM应用. 相反, 本书深入地讲解了ATL中模板类的结构. ATL如何实现COM的各种功能, 并且也向你展示了ATL中大量的技巧, 同时还指出了当前ATL中存在的一些错误和缺陷. 虽然本书介绍的技术有相当的深度, 但是作者的语言非常简练. 表达清晰. 结构安排也非常合理, 所以全书读起来并不艰涩, 期望中译本仍能够保持住这样的风格.
学习ATL需要具备良好的背景知识, 同样地, 阅读本书也需要具备必要的基础知识. 概括起来, 读者需要以下几方面的准备知识:
(1)COM基础. 因为ATL是针对COM的, 所以扎实的COM知识可以助你一臂之力. COM书籍目前已经很丰富了, 在阅读本书之前, 你可以先找一本书来打基础(译注).
(2)C++模板知识. 如果你能够很熟练地运用C++, 但是没有用过C++模板语法, 那么你可以阅读本书的附录A, 增加一点营养.
(3)Windows基础知识, 特别是Win32中有关窗口部分的知识. ATL 3. 0中有许多模板类涉及到窗口的概念, 如果你想用ATL开发一些包含用户界面(UI)的应用, 这些知识也是必需的. 本书最后三章讲述了有关窗口. 控制和控制包容的内容.
(4)STL知识. STL已经被纳入到C++标准中, 并且成为C++标准库中最重要的一员. ATL与STL在数据集合(collection)管理上有相通之处, 如果你有STL作基础, 那么理解ATL中的集合和枚举器部分可以轻松自如.
在这些准备知识中, 前三条比较重要, 而且大多数C++/COM程序员都已经具备, 所以这本书可以为他们进入ATL提供一条捷径. 最后一条不是必需的, 缺乏STL的知识不影响对于ATL大局的理解. 因为目前并没有很好的STL参考资料(也许很快会有), 所以读者可以自行斟酌决定.
最后, 我要说明的是, 这本书不是我一个人独立完成的. 我和新语的合作方式不是“你译一部分, 我译一部分, 然后合起来交稿”, 而是由新语完成全部初稿, 再由我审阅全部的内容. 书中的每一句话我都检查过, 如果读者发现任何翻译错误, 责任都在我, 敬请原谅.
潘爱民
2001年
于北京大学燕北园
C语言是产生汇编语言代码(ASM)的框架. 大多数ASM程序员在转移到C的过程中, 要花费大量的时间来检查和替换编译器产生的代码, 因为他们不相信编译器能够产生正确的代码. 随着时间的流逝以及编译器变得越来越好, ASM程序员渐渐地认识到, 他们可以信任编译器能够产生不仅正确, 而且高效的代码. 当然, 聪明的C程序员永远也不会忘记编译器在产生ASM代码. 他们知道, 当他们需要超越语言本身的能力的时候, 他们仍然能够到达指定的区域并且控制所产生的代码.
Microsoft的ATL(活动模板库, Active Template Library)是一个产生C++/COM代码的框架. 大多数C++程序员在转移到ATL的时候, 都非常害怕检查(更不用说替换)ATL产生的代码. 他们根本不信任ATL, 比ASM程序员不信任C编译器有过之而无不及, 因为对于初窥ATL的新手来说, ATL的源代码很是令人费解. 然而, ATL为C++/C0M程序员完成了同样的服务, 就如同C编译器为ASM程序员完成了同样的任务一样, 也就是说, ATL提供了一种更简单的方法来产生正确的. 高效的样板代码. 当然, 聪明的ATL程序员永远也不会忘记ATL在产生C++/COM代码. 当他们需要超越ATL本身的能力的时候, 他们仍然能够到达指定的区域并且控制所产生的代码.
本书就是为正在转移到ATL 3. 0(由Visual C++ 6. 0提供)的C++/COM程序员而写的. 因为ATL建立在一组假设的基础上, 所以要想成为一名有效率的ATL程序员, 你不仅需要理解ATL是如何建立起来的, 也需要理解ATL为什么要这样建立起来. 当然, 为了理解ATL为什么是这样的, 你必须要理解ATL开发所在的环境, 也就是COM. 本书并不把所有必要的COM知识浓缩到一章或者两章, 而是假定你已经知道了COM, 并向你展示ATL的设计. 用法和内部要点. 如果你希望在深入ATL之前先充实一下COM知识的话, 则Don Box的《Essential COM》(Addison-Wesley, 1998年是你获得COM知识的一个很好来源.
除了第1章之外, 本书从ATL的最底层一直到达最高层次, 每一章都建立在前面章节的内容的基础上. 第1章是一个简短的描述, 讲述了有关ATL的一些常见用法, 以及使用过程中涉及到的一些向导(wizard). 然而, 在第一章中, 一旦讲解过程中涉及到细节问题, 我会向你指出后面哪一章提供了进一步的深度讲解. 第2章到第5章展示了ATL的核心. 第2章讲述了ATL智能类型, 比如CComPrt. CComQIPtr. CComBSTR和CComVariant. 第3章讨论了ATL中如何实现对象, 焦点集中在当我们实现IUnknown时我们所拥有的大量选择方案. 第4章讨论了一些粘合代码, 当我们从COM服务器中暴露COM对象时这些代码是必需的. 第5章再次深入研究了IUnknown的实现, 这一次的焦点集中在如何实现QueryInterface上, 并展示了一些技术, 诸如tear-off接口和聚合等. 第6. 7. 8三章讨论了一些COM预制的标准接口的实现, ATL提供这些接口实现以便支持永久性. 连接点. COM集合和枚举器, 每一章讨论一个话题. 不管组件是否提供自己的用户接口, 它们往往会利用这些标准接口来提供相应的服务. 另一方面, 第9. 10. 11章焦点集中在建立独立的应用和用户界面组件上. 这些章节分别讲述了ATL窗口类. 控制(control)和控制包容(control containment). ATL源代码之所以难以阅读, 是因为它大量用到了模板的高级用法, 附录A提供了一组例子, 用来展示如何使用模板以及如何建立模板. 如果你以前曾经阅读过ATL的源码, 并且对于“为什么要把派生类的名字传递给基类模板”不太明白的话, 那么你会发现附录A非常有用. 附录B提供了重要的ATL类的列表, 以及声明这些类的对应头文件(通常也包含这些模板类的实现).
在写作这些章节的时候, 不仅显示图表和示例用法代码很有必要, 而且展示内部的ATL实现代码也很有用. 实际上, 本书通常会成为你阅读ATL源代码的向导指南, 所以你必须要区分哪些是作者编写的代码, 哪些是Microsoft雇员产生的代码, 我们采用下面的约定:
// This code is author-generated and is an example of what'you’d type.
// Bold-faced code requires your particular attention.
CComBSTR bstr = OLESTR(“Hello, World. ”),
// This code is part of ATL or Windows.
CComBSTR(LPCOLESTR pSrc)(m_str=SysAllocString(pSrv);
因为ATL开发小组并没有按照图书出版的需要来编写它们的代码, 所以通常有必要对ATL代码重新格式化, 甚至对原来的ATL代码作一些简化. 我尽了很大的努力来保持源代码的本质, 但是, 不管怎么样, ATL源代码总是最终的标准. 当你跟踪ATL类的实际实现代码时, 你会发现附录B非常有用.
如果你发现在本书的例子代码或者其他部分有任何错误, 你可以与Brent Rector(http:www. wiseowl.com)和Chris Sells(http://www. sellsbrothers.com)联系. 本书使用的源代码可以通过http://www. wiseowl.com/ATLInternals.htm获得.
作者感谢所有为本书做出贡献的家人. 虽然没有他们的努力, 这本书也有可能完成, 但是无论如何它不可能是现在的样子. Chris要感谢它的妻子Melissa以及他的儿子John和Tom, 感谢他们在无数个夜晚和周末陪伴他写作. Chris也要感谢Brent Rector, 让他加入到本书的写作工程上来.
Brent要感谢他的妻子Lisa以及孩子们Carly和Sean, 因为他们耽搁了本书的提交日程. 如果不是因为他们, 他有可能连续几天不会离开计算机. Brent也要感谢Chris的聪明才智. 耐心和英俊.
Brent和Chris要感谢许多朋友. 特别感谢Christian Beaumont. Jim Springfield. Walter Sullivan和Mark Kramer, 因为他们要忍受两位作者不停的提问, 他们总是花时间来回答这些问题. 也要特别感谢Don Box, 因为他在MSJ杂志上的ATL特载文章, 这些内容影响到了有关的课程, 并进而影响到本书. 感谢下面的各位评论家:Don Box. Keith Brown. Jon Flanders. Mike Francis. Kevin Jones. Stanley Lippman. Dharma Shukla. Jim Springfield. Jeff Stalls. Jaganathan Thangavelu和Jason Whittington. 特别感谢Dharma, 因为他的特殊的. 具有教育意义的评论. 感谢DevelopMentor的朋友, 讲师Fritz Onion深入钻研了ATL的控制包容. 感谢以前的一名学员Vladan Vidakovic, 因为他鼓励Chris深入钻研HTML控制. 感谢Tim Ewald. Jim Springfield和Don Box, 因为他们帮助开发了传递夹层(forwarding shim)技巧. 感谢ATL和DCOM邮件列表的成员, 特别是Don Box. Tim Ewald. Charlie Kindel. Valery Pryamikov. Mark Ryland和Zane Thomas. 最后(但不是最不重要)感谢Addison—Wesley, 特别是J. Carter Shanklim和Krysia Bebick, 因为提供了我们实际想要写作的环境.
我们也要感谢所有曾经仔细阅读了本书以前的印刷版本并发现了小错误的读者, 这些错误在这个版本中都已经被改正了. 这样的读者有:Elias Andersson. Ruben Bartelink. Vince Blasberg. Yao Cai. Yun Chang. Dan Corpron. Darron Devlin. Matevz Dolenc. Jerry Dungee. Jonathan Flanders. Nigel Foster. Michael Getfen. Thomas Goering. Khurram Haroon. Robert D. Herrick. Felipe Hervias. Robert Hill. Alan Kang. Yu—Ming Kao. Roland King. Adam Krumholz. Eric Lamontagne. Tasch Matthias. Godson Menezes. Jeffrey Metos. Hieu Nguyen. A. Nonymous. Michael Nyman. Joe o'Leary, Alan Parker. George Reilly. Kwak SeoungTae. Vivian De Smedt. Dan Sullivan. Jonathan Sun. Jeroen Thur. Alan Williamson和Ochi Wu. 特别感谢Ravi Singh, 因为他建议改进BullyEye控制, 以用于更为广泛的包容器环境中.