Let's look at what happens in an MFC Automation componentin 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 classCClock, for examplederived 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 Refreshno parameters or return value |
ShowWin | Method | Linked to class member function ShowWinshort 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.