Wrapping Objective Grid In an ATL ActiveX Control
ATL is very powerful when it comes to implementing COM functionality. It is very easy to implement dual interfaces. MFC, on the other hand, has somewhat convoluted COM support. It starts out being very easy to use, but 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. ATL is therefore usually the first choice when it comes to writing an ActiveX wrapper for any C++ code.
Combining ATL with a rich MFC UI library like Objective Grid 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.) 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 Objective Grid's 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 file it will be even smaller. Such a control will also be much more maintainable in the long run when compared to a native Win32 control. And, of course, consider all the time that will be saved when you reuse a powerful control such as Objective Grid instead of writing a Win32 based control from scratch.
Having laid out the case for the usefulness of Objective Grid 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. 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, then the cited approach is not efficient. That approach 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 an ATL object wizard that can be used to generate these controls easily. You can find this wizard under the Stingray category. After you have inserted an Objective Grid control, you can easily add methods and properties using the ATL wizards. With this wizard, writing an ATL based Objective Grid 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.
In use, you will only need to refer to the CGXGridWnd (or derived class) instance that is defined in the base class, m_wndClassImpl.
Figure 139 – The Objective Grid ActiveX control Object Wizard