Cosmo's Polyline as a DLL Object

All of the variations of the Koala object that we've seen earlier in this chapter are pretty boring and, well, useless. I bet you'd now like a component example that does something real. To demonstrate a more useful and exciting component, I've taken the Cosmo application from Chapter 1 and turned the C++ object CPolyline into an OLE component. The CHAP05\POLYLINE directory contains the implementation of this component using an in-process server, POLY05.DLL. Its registry entries are stored under the CLSID 00021147-0000-0000-C000-000000000046 (CLSID_Polyline5). This Polyline component provides objects with an incoming interface named IPolyline5 (which is equivalent to the C++ member functions on the original CPolyline) and an outgoing interface named IPolylineAdviseSink5 (which has the same member functions as the original CPolylineAdviseSink). To support this outgoing interface, the objects also implement IConnectionPointContainer and a connection point for IPolylineAdviseSink, demonstrating how connection points work between a real client and a real component. Both the IPolyline* interfaces are defined in INC\IPOLY5.H (their IIDs are defined in INC\BOOKGUID.H).

IPolyline5 contains member functions to deal with initialization, file I/O, data exchange, positioning of its window, and setting colors and line styles. As we progress through this book, we'll replace portions of this interface with standard OLE interfaces that provide the same capabilities, eventually building Polyline into a compound document object as well as an OLE control. For example, we can replace the file I/O members with the interfaces IPersistStorage and IPersistStreamInit, as we'll do in Chapter 8, and we can replace the data exchange members with IDataObject, as we'll do in Chapter 10. We'll also have occasion in Chapter 10 to replace the OnDataChange member of IPolylineAdviseSink5 with support for a separate outgoing interface called IAdviseSink, which also has an OnDataChange member. But throughout all these changes, the basic structure of the Polyline component, that is, its class factory, server structure, and object structure, will remain essentially the same.

IPolyline5 and IPolylineAdviseSink5 are examples of custom interfaces, but because we're implementing them on an in-process object we don't need any marshaling support. If we wanted to make a local server for Polyline, we'd have to create that marshaling support. The process of doing that is a topic for Chapter 6, but we'll demonstrate the mechanism on a somewhat simpler interface.

If you look at Polyline's source code, you'll notice that the CPolyline class still exists. The Polyline component uses this class internally to implement the object. This really demonstrates how you can take a C++ object and turn it into a shareable OLE component.

Of course, with Polyline split off into a separate component, Cosmo becomes a client of that component, which we'll now call Component Cosmo or CoCosmo. Its modified sample code is found in CHAP05\COCOSMO, in which modifications from the Chapter 1 version of Cosmo are offset by //CHAPTER5MOD and //End CHAPTER5MOD comments. This allows you to see exactly the sorts of things that a real client program would do to manage a component, including connection to an outgoing interface through connection points. Overall, Component Cosmo merely changed from being the user of a private C++ object, CPolyline, to being a client of the Polyline component through COM.