Static const AFX_DISPMAP * PASCAL _GETBASPASPATCHMAP (); /
Virtual const AFX_DISPMAP * getDispatchMap () const; /
#ELSE
#define declare_dispatch_map () /
PRIVATE: /
Static const AFX_DISPMAP_ENTRY _DISPATCHENTRIES []; /
Static uint _dispatchentrycount; /
Static DWORD _DWSTOCKPROPMASK; /
protected: /
Static AFX_DATA const AFX_DISPMAP DispatchMap; /
Virtual const AFX_DISPMAP * getDispatchMap () const; /
#ENDIF
-------------------------------------------------- ----
#ifdef _AFXDLL
#define begin_dispatch_map (Theclass, BaseClass) /
Const Afx_Dispmap * pascal theclass :: _ getBaseDispatchMap () /
{RETURN & BASECLASS :: DispatchMap;} /
Const Afx_Dispmap * Theclass :: getDispatchmap () const /
{RETURN & THECLASS :: DispatchMap;} /
AFX_COMDAT const AFX_DISPMAP THECLASS :: DispatchMap = /
{& THECLASS :: _ getBasedispatchMap, & theclass :: _ dispatchentries [0], /
& theclass :: _ dispatchentrycount, & thermlass :: _ dwstockpropmask}; /
AFX_COMDAT uint theclass :: _ dispatchentrycount = (uint) -1; /
AFX_COMDAT DWORD THECLASS :: _ DWSTOCKPROPMASK = (DWORD) -1; /
AFX_COMDAT const AFX_DISPMAP_ENTRY THECLASS :: _ dispatchentries [] = /
{/
#ELSE
#define begin_dispatch_map (Theclass, BaseClass) /
Const Afx_Dispmap * Theclass :: getDispatchmap () const /
{RETURN & THECLASS :: DispatchMap;} /
AFX_COMDAT const AFX_DISPMAP THECLASS :: DispatchMap = /
{& Baseclass :: DispatchMap, & Theclass :: _ dispatchentries [0], /
& theclass :: _ dispatchentrycount, & thermlass :: _ dwstockpropmask}; /
AFX_COMDAT uint theclass :: _ dispatchentrycount = (uint) -1; /
AFX_COMDAT DWORD THECLASS :: _ DWSTOCKPROPMASK = (DWORD) -1; /
AFX_COMDAT const AFX_DISPMAP_ENTRY THECLASS :: _ dispatchentries [] = /
{/
#ENDIF
#define end_dispatch_map () / {VTS_NONE, DISPID_UNKNOWN, VTS_NONE, VT_VOID, /
(AFX_PMSG) NULL, (AFX_PMSG) NULL, (SIZE_T) -1, AfxDispcustom}}; /
The way the idea is the same as the above interface map. Here is not detailed here.
About Automation Question, I think two days, specialize in writing an article.
Because Automation is indeed a wide range of technologies, what can I say?
Difficult, but there are many details, and the general discussion is unclear.
The structure that appears in the above macro is needed:
Struct AFX_DISPMAP_ENTRY
{
LPCTSTSTR LPSZNAME; // Method or attribute name
Long ldispid; // Interface distribution ID (May Be Dispid_Unknown)
LPCSTR LPSZPARAMS; // Parameters
Word vt; // Return value type or attribute type
AFX_PMSG PFN; // Normal Member ON
AFX_PMSG PFNSet; // Special Member for OnSet
Size_t npropoffset; // offset, this place is the core
AFX_DISPMAP_FLAGS FLAGS; // Flags (E.G. Stock / Custom)
}
Struct AFX_DISPMAP
{
#ifdef _AFXDLL
Const AFX_DISPMAP * (PASCAL * PFNGETBASEMAP) ();
#ELSE
Const AFX_DISPMAP * PBASEMAP;
#ENDIF
Const AFX_DISPMAP_ENTRY * LPENTRIES;
Uint * LpenTryCount;
DWORD * LPSTOCKPROPMASK; / / Do you use a spare name
}
In summary, even when the component class finds an interface, the method or change attribute is executed in the way, it is not performed directly.
Part 5 ------- Component Terrace: Several core functions
Naturally, the use of components is not always, starting from the call interface query function,
The program is started to find and create the process:
NO1.
ColeObjectFactory :: registerall ();
When the application is initialized, call. Where is the purpose? None is the registered factory.
(This place, I think it is loaded with all kinds of works.
Because you can directly use the class factory pointer in the pointer chain directly)
NO2.
AFX_MANAGE_STATE (AFXGETSTATICModuleState ());
In the core of the CWINAPP object developed by MFC
In the component, AFX_Manage_State (AFXGETSTAICMODULESTATE ());
You must call before the specific operation because it masters all the information.
In ATL, CCOMMODEL objects, coordinated inside.
Everything is scheduled by the CCOMMODEL object.
NO3.
AFXDLLLGETCLASSOBJECT (RCLSID, RIID, PPV);
You want to get the hoped interface pointer, and get the steps of the classroom pointer is necessary.
Getting the factory pointer is AFXDLLGETCLASSOBJECT (RCLSID, RIID, PPV);
Completed, it must be called before use
AFX_MANAGE_STATE (AFXGETSTATICModuleState ());
To monitor the status,
code show as below:
Scode AFXAPI AFXDLLGETCLASSOBJECT (Refclsid Rclsid, Refiid Riid, LPVOID * PPV)
{
* ppv = NULL;
DWORD LDATA1 = rclsid.data1; // search factory defined in The Application
AFX_MODULE_STATE * PModuleState = AFXGETMODULESTATE ();
AfxlockGlobals (crit_ObjectFactoryList);
For (ColeObjectFactory * pFactory = PModuleState-> m_factorylist;
Pfactory! = null; pfactory = pfactory-> m_pnextfactory)
{
IF (pfactory-> m_bregistered! = 0 &&
LDATA1 == PFactory-> m_clsid.data1 &&
((DWORD *) & rclsid) [1] == ((DWORD *) & pfactory-> m_clsid) [1] &&
((DWORD *) & rclsid) [2] == ((DWORD *) & pfactory-> m_clsid) [2] &&
((DWORD *) & rclsid) [3] == ((DWORD *) & pfactory-> m_clsid) [3])
{
// Found Suitable Class Factory - Query for Correct Interface
Scode SC = PFactory-> InternalQueryInterface (& RIID, PPV);
AFXUNLOCKGLOBALS (crit_ObjectFactoryList);
Return SC;
}
}
AFXUNLOCKGLOBALS (crit_ObjectFactoryList);
#ifdef _AFXDLL
AfxlockGlobals (crit_dynlinklist);
// Search Factories Defined in Extension DLLS
For (cdynlinklibrary * pdll = pmodulestate-> m_libraryList; pdll! = null;
PDLL = PDLL-> M_PNEXTDLL)
{
FOR (PFactory = PDLL-> m_factorylist;
Pfactory! = null; pfactory = pfactory-> m_pnextfactory)
{
IF (pfactory-> m_bregistered! = 0 &&
LDATA1 == PFactory-> m_clsid.data1 &&
((DWORD *) & rclsid) [1] == ((DWORD *) & pfactory-> m_clsid) [1] &&
((DWORD *) & rclsid) [2] == ((DWORD *) & pfactory-> m_clsid) [2] &&
((DWORD *) & rclsid) [3] == ((DWORD *) & pfactory-> m_clsid) [3])
{
// Found Suitable Class Factory - Query for Correct Interface
Scode SC = PFactory-> InternalQueryInterface (& RIID, PPV);
AfXunlockGlobals (crit_dynlinklist);
Return SC;
}
}
}
AfXunlockGlobals (crit_dynlinklist);
#ENDIF
// Factory Not Registered - Return Error
Return Class_e_classNotavailable;
}
Code brief description:
First, when the component exports the function DllgetClassObject via CLSID and IID, first
The program environment will be monitored, then call AFXDLLGETCLASSOBJECT, and AfxdllgetClassObject
The internal operation is like this, which will be maintained in the global information maintained (
There are also registered types of customs, resource handles, etc., according to CLSID search
The corresponding class is searching in the extended DLL referenced by this DLL.
OK! Basically, the MFC's basic support of COM is through the above macro.
Realize ...
-------------------------------------------------- ----------------------------------
Treatment of ATL
-------------------------------------------------- ----------------------------------
Solemnly declare:
Allow copy, modification, delivery, or other behavior
However, it is not allowed for any commercial use.
Written at 1/4/2003
Last modified: 1/4/2003
By redstar81
81_redstar@163.com
-------------------------------------------------- ----------------------------------