An MFC Automation Component

Let's look at what happens in an MFC Automation component—in this case, a simplified version of the EX25C alarm clock program that is discussed later in this chapter. In the MFC library, the IDispatch implementation is part of the CCmdTarget base class, so you don't need INTERFACE_MAP macros. You write an Automation component class—CClock, for example—derived from CCmdTarget. This class's CPP file contains DISPATCH_MAP macros:

BEGIN_DISPATCH_MAP(CClock, CCmdTarget)
    DISP_PROPERTY(CClock, "Time", m_time, VT_DATE)
    DISP_PROPERTY_PARAM(CClock, "Figure", GetFigure,
                        SetFigure, VT_VARIANT, VTS_I2)
    DISP_FUNCTION(CClock, "RefreshWin", Refresh, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION(CClock, "ShowWin", ShowWin, VT_BOOL, VTS_I2)
END_DISPATCH_MAP()

Looks a little like an MFC message map, doesn't it? The CClock class header file contains related code, shown here:

public:
    DATE m_time;
    afx_msg VARIANT GetFigure(short n);
    afx_msg void SetFigure(short n, const VARIANT& vaNew);
    afx_msg void Refresh();
    afx_msg BOOL ShowWin(short n);
    DECLARE_DISPATCH_MAP()

What does all this stuff mean? It means that the CClock class has the following properties and methods.

Name Type Description
Time Property Linked directly to class data member m_time
Figure Property Indexed property, accessed through member functions GetFigure and SetFigure: first parameter is the index; second (for SetFigure) is the string value (The figures are the "XII," "III," "VI," and "IX" that appear on the clock face.)
RefreshWin Method Linked to class member function Refresh—no parameters or return value
ShowWin Method Linked to class member function ShowWin—short integer parameter, Boolean return value

How does the MFC dispatch map relate to IDispatch and the Invoke member function? The dispatch-map macros generate static data tables that the MFC library's Invoke implementation can read. A controller gets an IDispatch pointer for CClock (connected through the CCmdTarget base class), and it calls Invoke with an array of pointers as a parameter. The MFC library's implementation of Invoke, buried somewhere inside CCmdTarget, uses the CClock dispatch map to decode the supplied pointers and either calls one of your member functions or accesses m_time directly.

As you'll see in the examples, ClassWizard can generate the Automation component class for you and help you code the dispatch map.