An MFC Automation Component
Let's look at what happens in an MFC Automation component—in this case, a simplified version of the Ex23c alarm clock program that's 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—that's 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 | An indexed property that's accessed through member functions GetFigure and SetFigure. The first parameter is the index, and the 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 the class member function Refresh. It has no parameters or return value. |
ShowWin | Method | Linked to the class member function ShowWin. It is a short integer parameter with a 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 (which is 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, which is 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, the Add Class Wizard can generate the Automation component class for you and help you code the dispatch map.