Stingray Studio : Objective Edit User’s Guide : Chapter 9 ATL and Objective Edit : Wrapping Objective Edit in an ATL ActiveX Control
Wrapping Objective Edit in an ATL ActiveX Control
ATL is usually the first choice for writing an ActiveX wrapper for any C++ code. It is very powerful when it comes to implementing COM functionality; it makes it very easy to implement dual interfaces. MFC, on the other hand, has somewhat convoluted COM support. While MFC starts out being very easy to use, more often than not, it ends up being rather difficult to maintain and extend. Also, dual interfaces are somewhat more difficult to implement with MFC than they are with ATL.
Combining ATL with a rich MFC UI library like Objective Edit can produce an ActiveX control that is reusable, extensible, and customizable. We can easily link statically to MFC, thus eliminating the need for redistributing the MFC DLL. (MFC ActiveX controls cannot be linked statically to the MFC DLL.) One issue is that these controls will be somewhat larger than controls that are written in native Win32 without MFC. However, with the use of advanced optimization techniques and just plain clever linking, it is possible to have a lean control. Using optimization techniques it is possible to create a very basic grid ActiveX control, with ATL used for the COM implementation, for under 600k. Remember that this control will have no dependency on MFC run times. Packaged in a CAB (compressed Cabinet) file, it will be even smaller. Such a control will also be much more maintainable in the long run than a native Win32 control would be. And, of course, consider all the time that will be saved when you reuse a powerful control such as those included in Objective Edit instead of writing a Win32 based control from scratch.
Having laid out the case for the usefulness of Objective Edit ATL ActiveX controls, let us look into implementation issues. The most common way to use MFC controls inside of ATL ActiveX controls is to create the MFC control window as a child of the ATL control window. This approach is useful if the MFC control is a small part of the control UI and functionality. However, in this section, we are more concerned with ActiveX controls that expose MFC based controls, with the MFC control forming the dominant part of the UI and functionality. If this is the case, this approach is not efficient as it results in the creation of two windows (one by the ATL control and one by the embedded control). Having a parent window that is essentially unused is a significant drawback, and creates several problems. Though these problems can be worked around, it is desirable to have one control window.
We have come up with an easy approach that allows the usage of one window in cases such as these. This solution basically involves chaining together the MFC message maps (in turn the MFC window procedure) and the ATL message maps. We have implemented a base class that does much of this work. We have also included a set of ATL object wizards that can be used to generate these controls easily. You can find these wizards under the Stingray category. After you have inserted an Objective Edit control, you can easily add methods and properties using the ATL wizards. With this type of wizard support, writing an ATL based Objective Edit ActiveX control is very easy. The generated control exposes a few predefined properties and methods that you can remove as required. These are provided as sample code.