Developers have been using MFC to create ActiveX controls since mid-1994. In many ways, MFC is a mature framework for developing controls. Microsoft Visual Studio includes an MFC ActiveX Control Wizard for generating a DLL containing one or more ActiveX controls. For each control that you ask the wizard to generate, you get a class derived from MFC's COleControl class and a default property page for the control. The object produced by the wizard implements just about everything required to be a control, including the OLE Embedding protocol, an incoming IDispatch interface, an outgoing event interface with connection points, and persistence.
An MFC-based ActiveX control contains all the boilerplate code necessary to be a control and includes many well-defined points for adding features that distinguish your control from other controls. For example, MFC's COleControl class implements a function named OnDraw that gives you a device context on which you can render your control. The property pages for your control are already wired up correctly—developing a property page for your control is as easy as developing a normal MFC-based dialog box. And adding methods, properties, and events to your control is simply a matter of using the ClassWizard.
One of the downsides of using MFC to create ActiveX controls is that your development effort is then bound to MFC, which can be limiting. For example, sometimes you want your controls to be smaller or to work even if the end user doesn't have the MFC DLLs on his or her system. MFC-based controls include the full complement of OLE control-oriented interfaces and require the MFC library to be available (either through dynamic or static linking). Using MFC to create ActiveX controls also forces you to make certain design decisions. For example, if you decide to use MFC to write an ActiveX control, adding dual interfaces is quite tedious (unless you feel like writing a lot of extra code). In addition, using MFC to create ActiveX controls means the control and its property pages must use IDispatch to communicate.
To avoid these issues, you can use ATL to create ActiveX controls. ATL includes the facilities to create full-fledged ActiveX controls, complete with all the features they should have—incoming interfaces, persistent properties, property pages, and connection points, to name a few. Compared to writing an ActiveX control using MFC, ATL provides a lot of flexibility.
As with any other ATL-based COM DLL, the easiest way to create a server to hold your controls is to use the ATL COM AppWizard. Take a look at Chapter 9 for more details on the ATL COM AppWizard. Once the DLL has been generated, just use the Object Wizard to add controls. Visual Studio provides a wide variety of wizards for generating controls. The next section gives you a rundown of the different kinds of controls you can create using ATL.