分享
 
 
 

深入探索COM开发框架 之 MFC和ATL [四]

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

static const AFX_DISPMAP* PASCAL _GetBaseDispatchMap();

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, &theClass::_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, &theClass::_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 } };

思路跟上面的接口映射表的如出一辙.这里不详细叙述.

关于Automation问题,我想过两天,专门写一篇文章谈谈.

因为Automation的确是一门范围很广的技术,不能说有多么的

难,不过细节很多,而且普遍的论述概念不清.

在上面几个宏中出现的结构倒需要提一下:

struct AFX_DISPMAP_ENTRY

{

LPCTSTR lpszName; // 分发的方法或属性名

long lDispID; // 接口分发ID (may be DISPID_UNKNOWN)

LPCSTR lpszParams; // 传递的参数

WORD vt; // 返回值类型或属性类型

AFX_PMSG pfn; // normal member On<membercall> or, OnGet<property>

AFX_PMSG pfnSet; // special member for OnSet<property>

size_t nPropOffset; // 偏移量,这个地方是核心

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; //是否用备用的名称

};

总之,即使在组件类寻到接口时,会按分发的方式来执行方法或更改属性,不会直接执行.

PART5-------组件得以使用的纽带:几个核心函数

自然,组件的使用不是一呼既来的,从调用接口查询函数开始,

程序内部就开始了漫漫的寻找和创建过程 :

no1.

COleObjectFactory::RegisterAll();

在应用初始化时,调用.目的何在 ? 无非是注册类厂.

(这个地方,本人认为是加载了所有的类厂对象.

因为下面可以直接使用类厂指针链中的类厂指针了)

no2.

AFX_MANAGE_STATE(AfxGetStaticModuleState());

在MFC开发的以CwinApp对象为核心的

组件中, AFX_MANAGE_STATE(AfxGetStaticModuleState());

必须在具体操作前调用,因为它掌握着程序所有的信息.

而在ATL中,CcomModel对象,内部进行了协调.

一切行为由CcomModel对象来调度.

No3.

AfxDllGetClassObject(rclsid, riid, ppv);

你想得到希望的接口指针,获得类厂指针这一步是必须的.

而获得类厂指针是AfxDllGetClassObject(rclsid, riid, ppv);

完成的,它在使用前必须调用

AFX_MANAGE_STATE(AfxGetStaticModuleState());

来监视程序状态,

代码如下:

SCODE AFXAPI AfxDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)

{

*ppv = NULL;

DWORD lData1 = rclsid.Data1;

// search factories 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;

}

代码简要说明:

在通过CLSID和IID调用组件导出函数DllGetClassObject时,首先

会监测程序环境,然后调用AfxDllGetClassObject,而AfxDllGetClassObject

内部的操作是这样的,它会从程序维护的全局信息中(

还有进线程信息、资源句柄等)的注册的类厂表中,根据CLSID搜索

相应的类厂,则从本dll引用的扩展dll中搜索.

OK !基本上,MFC对于COM的基础支持,就是通过上面这些宏

来实现的…

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

待续 ATL篇

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

郑重声明:

允许复制、修改、传递或其它行为

但不准用于任何商业用途.

写于 1/4/2003

最后修改: 1/4/2003

By RedStar81

81_RedStar@163.com

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有