In-depth exploration of MFC and ATL [four]

zhaozj2021-02-16  46

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 OR, ONGET

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

-------------------------------------------------- ----------------------------------

转载请注明原文地址:https://www.9cbs.com/read-23582.html

New Post(0)