Electronic Review of Computer Books

[ ERCB Home | New | Feature | Brief | DDJ | Letters | Links ]

[an error occurred while processing this directive]

Vital Statistics

Title ATL Internals
Authors Brent Rector and Chris Sells
Publisher Addison-Wesley Longman
Reading, Massachusetts
http://www.awl.com/
Copyright 1999
ISBN 0-201-69589-8
Pages 674
Media CD-ROM
Price $54.95


Learning ATL from the Source Code

Familiarizing oneself with the COM programming discipline is quickly becoming a must for any serious Windows developer facing the next millennium. On the other hand, truly understanding and applying COM is also pretty difficult, from both a design-level standpoint and a more practical implementative perspective. While the former necessarily permeates every powerful component-based technology model, the second one can be simplified by using high-level development tools that shield the programmer from a lot of details at the cost of some limitations in flexibility and performance. Those are the motivations that lead many developers to embrace Visual Basic or Java for their COM undertakings.

But there are still many hardcore engineers who want (and sometimes need, depending on the requirements of their projects) to get the most out of COM and are therefore unwilling to accept any of the compromises offered by such tools. For this category of developers, the appropriate programming language turns out to be C++, the only one to fully bring the power of the model, but at the cost of a higher degree of complexity. The Active Template Library (better known as ATL) was created explicitly for these die-hard programmers to take off at least part of the burden of implementing COM components by providing significant reusable code and handy wrappers, while strictly remaining faithful to the imperative goals of maximum flexibility and limited overhead in the resulting binaries. ATL Internals was created to provide those die hard ATLers with exhaustive information on each and every aspect of the framework -- with no compromises.

The background of the ideal reader of ATL Internals should include experience in C++ (including the more advanced aspects, most notably templates), proficiency in pure COM programming, and a commitment to learn how to use ATL from the foundations up to the more esoteric features. The approach openly puts a strong emphasis on explaining why certain features of the framework were implemented in a certain way to achieve certain results, opposing the usual style (adopted by far too many texts) of illustrating the concepts as in a list of linked elements, with no focus on the cohesive technical reasons beneath their validity.

The fundamental idea is that the library, as it ships, constitutes the result of many man-months of research, design, and comparisons of different alternatives and trade-offs made by a team of highly skilled COM engineers possessing substantial experience. So in analogy, the only manner to actually master the internals and mechanisms of it is by possessing a solid knowledge of COM in advance, and augmenting with a thorough deconstruction of the technical issues that led to the creation of ATL as we see it today. There is heavy reliance on the published source files to match the concepts and the proposed motivations with actual compilable code (which is an important upside). The result is an extremely detailed manual covering each and every bit of ATL in depth, so much that it could almost serve as the development team’s insider specification for the project (the parallel with bestseller MFC Internals does not stop in the title in this respect). The topics range from interface maps to servers, from ActiveX control creation to hosting, passing through the auxiliary data wrappers, connection points, and UI-related templates. But the quality remains at high levels throughout the entire book.

A bit late in hitting the shelves, ATL Internals is definitely a book worth having (and reading) if you are serious about ATL 3.0. Compared to its most direct competitor, Professional ATL COM Programming, this book is less example-driven and spends less time indoctrinating the reader on the theory of COM or on general utilization of ATL in working scenarios. Which of the two is the best? Professional ATL COM Programming better fits the needs of the ATL developers that have a somewhat incomplete knowledge of COM and seek a pragmatic, full-of-examples path to ATL proficiency. But ATL Internals is the number one resource they will continuously find themselves referring to for gaining true mastery of every ATL-related topic and to rule out the situations not clearly addressed by the official documentation.

In short, buy a copy of both, but if you have room for only one on your desk at the office, this is the right one to always keep at hand.

-- Davide Marcato (marcato@programmers.net or http://www.DavideMarcato.com)


Table of Contents

Preface

Chapter 1. Hello, ATL

Chapter 2. Data Manipulation Classes

Chapter 3. Objects in ATL

Chapter 4. Servers in ATL

Chapter 5. Interface Maps

Chapter 6. Persistence

Chapter 7. Enumeration

Chapter 8. Connection Points

Chapter 9. Windowing

Chapter 10: Controls

Chapter 11: Control Containment

Appendix A. C++ Templates by Example

Appendix B. ATL Classes and Headers


Excerpts from ATL Internals

From Chapter 5 -- "Interface Maps," page 211

Recall: COM Identity

From a client perspective, the rules of AddRef and Release are fairly stringent. Unless the client is careful about their use, objects could go away before expected or stay around too long. The object, however, is allowed to implement AddRef and Release in any number of ways, depending on how it would like to manage its own lifetime, for example, as a heap based, stack based, or cached object.

On the other hand, QueryInterface is pretty easy to get right on the client side. Any client can ask an object if it supports any other functionality with a simple call. However, clients expect certain relationships between the interfaces on a COM object. These expectations form the laws of COM identity.

The Laws of COM Identity

The laws of COM identity say the following things about how an object must expose its interfaces via QueryInterface.

· A client must be able to get directly to any interface implemented by the object via QueryInterface.

· An object’s interfaces must be static for its life.

· QueryInterface for IUnknown must always succeed and must always return the same pointer value.

From Chapter 8 -- "Connection Points," page 365

"here, Oh Where Are the Connection Points? Where, Oh Where Can They Be?

Any implementation of IConnectionPointContainer needs some fundamental information: a list of connection point objects and the IID supported by each connection point object. The ATL implementation uses a table called a connection point map in your connectable object’s class declaration using three ATL macros.

The BEGIN_CONNECTION_POINT_MAP macro specifies the beginning of the table. The only parameter is the class name of the connectable object. Each CONNECTION_POINT_ENTRY macro places an entry in the table and represents one connection point. The macro’s only parameter is the IID of the interface supported by the connection point.

Note that the CONNECTION_POINT_ENTRY macro requires you to specify an IID, whereas the COM_INTERFACE_ENTRY macro needs an interface class name. Historically, you could always prepend an IID_ prefix to an interface class name to produce the name of the GUID for the interface. Prior versions of ATL’s COM_INTERFACE_ENTRY macro actually did this to produce the appropriate IID.

However, source interfaces have no such regular naming conventions. Various versions of MFC, MKTYPLIB, and MIDL have generated different prefixes to a dispinterface. The CONNECTION_POINT_ENTRY macro thus couldn’t assume a prefix and therefore required you to specify the IID explicitly.

As of version 3.0, ATL uses, by default, the __uuidof keyword to obtain the IID for a class. Unfortunately, changing the CONNECTION_POINT_ENTRY macro to expect a class name would break existing code.

The END_CONNECTION_MAP macro generates an end-of-table marker and a static member function that returns the address of the connection map and its size.

From Chapter 11 -- "Control Containment," page 554

As attractive as the CreateControl, CreateControlEx, and AttachControl member functions are, however, as of ATL 3.0, you should avoid using them. They leak. Phase one creates an instance of CaxHostWindow, even if the window text is empty. All three of the second-phase control creation functions also create an instance of CAxHostWindow and never destroy the first one. You’re leaking the size of a CAxHostWindow object (224 bytes) every time you call one of these functions.

Luckily, there’s a workaround. If you use the QueryHost member function of CAxWindow, you can obtain the IAxWinHostWindow interface on the existing CAxHostWindow object:

template <class TBase = CWindow> class CAxWindowT : public TBase {

...

The QueryHost member functions uses the AtlAxGetHost function to send a custom window message to the AtlAxWin window to obtain an interface pointer on the host. Once you have the IAxWinHostWindow interface, you can call the interface member functions CreateControl, CreateControlEx, or AttachControl without worrying of leaking because now you’re reusing the existing CAxHostWindow instead of creating a new one. For example: ...

 


Quick Rating

Readability Star Star Star
Originality Star Star Star HalfStar
Organization Star Star Star HalfStar
Accuracy Star Star Star Star
Consistency Star Star Star HalfStar
Depth Star Star Star HalfStar
Timeliness Star Star HalfStar
Editing Star Star Star
Design Star Star HalfStar
Overall Value Star Star Star HalfStar

Explanation of ERCB rating scale: No stars = unacceptable, 1 Star = marginal, 2 Stars = average, 3 Stars = above average, 4 Stars = exceptional.


Copyright ©1999 Electronic Review of Computer Books
Created 5/6/1999 / Last modified 5/6/1999 / webmaster@ercb.com