After generating an ATL-based server, our next step is to add COM object implementation classes. The ATL framework assumes that you are going to add one C++ class for each COM object in the server. Visual C++ supports two different ways to add a COM object into ATL: using Insert New ATL Object and using New Class.
Insert a new ATL object:
An ATL object can also be added into a project using New ATL Object from the Visual C++ Insert menu.
This brings up the ATL Object Wizard. To add a basic COM object, select Simple Object.
Click the Next button. This brings up the ATL Object Wizard Properties dialog.
We did not use this method because it does not allow us to specify more than one interface in a COM object! To add a second interface, we
would have to add code manually several places within the project.
We will use New Class in this course to add a C++ implementation class for a COM object:
We have now added a C++ class, CPhBookObj, that implements COM object PhBookObj and its two interfaces, IReadPhBook and IManagePhBook. We will take a closer look at the results of our efforts, for example, files and code--in the following lessons.
Steps requires to add C++ implementation Class for a COM object
Here are the steps requires to add a C++ implementation class for a COM object:
In the Workspace window, the Class View tab is selected. At the top of the ClassView pane, right-click on PhBook classes.
In the pop-up menu, click New Class to open the New Class dialog.
The New Class dialog opens. Under Class Information, type CPhBookObj. Next to Interface type, check Custom.
In the Interfaces section, set Number of interfaces: to 2.
Notice that two interfaces are now named. Next we will change the default names given to the two interfaces. Select the Edit... button in the Interfaces section.
The Edit Interface Information dialog opens. We want to change the name of the first interface to IReadPhBook. Double-click on IPhBookObj in the Interfaces Names: list box. Replace IPhBookObj with IReadPhBook. Change the name of the second interface.
Double-click on IPhBookObjInt2 and replace it with IManagePhBook. Once the interface names have been changed, click OK in the Edit Interface Information dialog.
We return to the New Class dialog. Make sure the Aggregatable check box at the bottom of the New Class dialog is checked. Click OK to accept the new COM object.
The new COM object is completed. The object and its two interfaces are added to the PhBook classes. This is the end of the simulation.
COM Programming is interface-based
The most important concept to understand about COM programming is that it is interface-based.
You do not need real COM or even Microsoft runtime support to use interface-based programming. All you need is some discipline.
In the following spaceship example, we start with a single class named CSpaceship that implements
several functions. C++ developers usually sit down at the computer and start typing a class like this:
class CSpaceship
{
void Fly();
int&GetPosition();
};
With interface-based COM development the procedure is a little different . Instead of writing the class directly, interface-based programming involves spelling out an interface before implementing it. The Fly() and GetPosition() functions were moved into an abstract base class named IMotion.
Then we inherit the CSpaceship class from the IMotion interface like this:
class CSpaceship : IMotion
{
void Fly();
int& GetPosition();
};
Interface separates Implementation
Notice that at this point the motion interface has been separated from its implementation. When practicing interface development, the interface comes first. You can work on the interface as you develop it, making sure it is complete. But once the interface has been published and is being used by other developers, the interface is set in stone and cannot change. This subtle distinction between class-based programming and interface-based programming seems to introduce some programming overhead. However, it turns out to be one of the key points to understanding COM. By collecting the Fly() and the GetPosition() functions in an interface, you have developed a binary signature. That is, by defining the interface ahead of time and talking to the class through the interface, client code has a potentially language-neutral way of talking to the class. Gathering functions together into interfaces is itself quite powerful. Imagine you want to describe something other than a spaceship, an airplane, for example. It's certainly conceivable that an airplane would also have Fly() and GetPosition() functions. Interface programming provides a more advanced form of polymorphism, polymorphism at the interface level, not only at the single-function level.
Separating interface from implementation is the basis of interface-based development. The Component Object Model is centered on interface programming. COM enforces the distinction between interface and implementation. In COM, the only way client code can talk to an object is through an interface. However, gathering functions
together into interfaces isn't quite enough. There's one more ingredient needed, a mechanism for discovering functionality at runtime.
COM Frameworks
Some tools are already available to help reduce the frustration induced by OLE and COM. For example, the Microsoft Foundation Class (MFC) framework is designed to make it as easy as possible for C++ developers to write applications and components that take advantage of OLE by providing a set of classes that encapsulate its use. Microsoft Visual Basic, the most popular Microsoft development tool, distances developers even further from the complexity of OLE. However, only with the release of the Visual Basic Custom Control Edition was it possible to develop COM objects using Visual Basic. Until then, Visual Basic
had been a tool only for COM consumers, not for COM developers.
Certainly, developing COM objects using MFC and Visual Basic is much easier than trying to create them using raw C or C++. In fact, for all but the most advanced developers, attempting to face the wrath of COM without the shelter of a framework can be tantamount to developer suicide; those frameworks have been the only feasible approach. Along with the benevolent level of abstraction they provide, however, MFC and Visual Basic carry a fairly stiff penalty: they both saddle applications and components with a large run-time dynamic-link library (DLL). This extra freight inherent in MFC and Visual Basic has created a chasm between "lean and mean" COM development using straight C and C++ and the "dumb, fat and happy"
approach taken by those frameworks.
Enterprise edition of Visual C++:
A few years ago, in an attempt to provide solutions to the problems facing COM developers within Microsoft, several members of the Visual C++ development team were formed into a new team created to design the Enterprise edition of Visual C++, code-named Galileo. The new team determined that internal corporate developers were adopting a multitiered strategy wherein application logic is divided into roughly three layers: user services, business services, and data services, as described in the following sidebar.
Add Com Object - Exercise
Click the Exercise link to apply what you have learned about adding a C++ implementation class to a COM object. Add COM Object - Exercise