Basic Control Architecture

[Previous] [Next]

The interfaces mentioned in the control listings allow the client and the object to behave as advertised. We'll tackle these interfaces in time, and later chapters will cover them in depth. However, the heart of an ATL-based ActiveX control lies within CComControl and its base classes. Let's start by examining the CComControl class. This section offers you an overview of ATL's control architecture.


You can find CComControl in Microsoft's atlctl.h file under ATL's include directory. CComControl is a template class that takes a single class parameter and is defined as shown here:

 template <class T> class ATL_NO_VTABLE CComControl :  public CComControlBase,      public CWindowImpl<T> {  }; 

CComControl by itself is a lightweight class that doesn't have a lot going on—it derives from CComControlBase and CWindowImpl. CComControl expects the template parameter to be an ATL-based COM object derived from CComObjectRootEx. CComControl requires the template parameter for various reasons. For example, the class uses the template parameter to call back to the control's _InternalQueryInterface.

CComControl implements several functions that make it easy for the control to call back to the client. For example, CComControl implements a function named FireOnRequestEdit that gives controls the ability to tell the client that a specified property is about to change. FireOnRequestEdit calls back to the client through the client-implemented interface IPropertyNotifySink. This method notifies all connected IPropertyNotifySink interfaces that the property specified by a certain DISPID is about to change.

CComControl also implements FireOnChanged, which is very much like FireOnRequestEdit in that it calls back to the client through IPropertyNotifySink. However, FireOnChanged is useful for telling the control's clients (all clients implementing IPropertyNotifySink) that a property specified by a certain dispatch ID (DISPID) has already changed.

CComControl implements a function named ControlQueryInterface that simply forwards to the control's IUnknown. Finally, CComControl implements a function named CreateControlWindow. The default behavior for this function is to call CWindowImpl::Create. (Notice that CComControl also derives from CWindowImpl.) If you want, you can override this method to do something other than create a single window. For example, you might want to create multiple windows for your control.

Most of the real functionality for CComControl exists within the CComControlBase and CWindowImpl classes. Let's take a look at those classes now.


CComControlBase is much more substantial than CComControl. To start, CComControlBase maintains all the pointers the control uses to talk back to the client. CComControlBase uses ATL's CComPtr smart pointer to wrap its interfaces implemented for calling back to the client. Its member variables include wrappers for IOleInPlaceSite, an advise holder for the client's data advise sink, an OLE advise holder for the client's OLE advise sink, and a wrapper for IOleClientSite. CComControlBase also uses ATL's CComDispatchDriver to wrap the client's dispatch interface for exposing its ambient properties.

CComControlBase is where you'll find the control's sizing and positioning information, which is maintained as member variables. The other important data member within CComControlBase is the control's window handle. Most ActiveX controls are user interface gadgets and therefore maintain a window. CWindowImpl and CWindowImplBase handle the windowing aspects of an ATL-based ActiveX control.

CWindowImpl and CWindowImplBase

CWindowImpl derives from CWindowImplBase, which in turn derives from CWindow and CMessageMap. As a template class, CWindowImpl takes a single parameter upon instantiation. The template parameter is the control that's being created. CWindowImpl needs the control type because CWindowImpl calls back to the control during window creation to do such things as create the control window.

In addition to wrapping the basic window functionality (wrapping ShowWindow, MoveWindow, SendMessage, and so on), the ATL windowing classes implement a sophisticated message-routing mechanism. We'll take a look at that mechanism when we cover ATL windowing in depth in Chapter 14.

Now you've seen the basic control architecture. Let's take a look at the various tasks involved in developing an ActiveX control, including writing code to render the control, developing an incoming interface, managing properties, and firing events.

Inside Atl
Inside ATL (Programming Languages/C)
ISBN: 1572318589
EAN: 2147483647
Year: 1998
Pages: 127 © 2008-2017.
If you may any questions please contact us: