分享
 
 
 

ATL仿真

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

这几天学习ATL,想起了《深入浅出MFC》中的方法:仿真,折腾了大半天,弄出了点东西,愿与正在ATL的坚韧难懂中挣扎却不懈努力的同志共享。编写的时候我怕写成了ATL的COPY所以没有看它的源码,很多名字只凭记忆,还有些名字我觉得我所取的名字自己更易理解,所以名字可能有点不同,别怪我!由于怕又陷入了那个大迷宫里,所以没有客气的把一些初学者不好理解的东西都“砍掉”,比如,我在仿真时完全没有考虑聚合的情况。另外,我没有引用其它类库的东西(以免你要到处找类库手册),甚至没有没有用API。里头加了些注解。不说了,你看吧!但愿对你有点用。

//---------AtlMy.h

#include <iostream.h>

//常用类型定义

typedef unsigned long HRESULT;

typedef unsigned short WORD;

typedef unsigned long DWORD;

typedef int BOOL;

//返回值

#define S_OK 0

#define E_FAIL 1;

#define INTERFACE class

#ifdef _DEBUG_ON

#define ASSERT(b) {if(!b) __asm int 3h}

#else

#define ASSERT(b)

#endif

//计算接口的偏移

#define _ATL_PACKING 8

#define offsetofclass(base, derived) ((DWORD)(static_cast<base*>((derived*)_ATL_PACKING))-_ATL_PACKING)

//标识符类型定义

typedef unsigned long GUID;

typedef GUID IID;

typedef GUID CLSID;

#define DEFINEIID(X,N) const IID_##X = N

//调试输出

#ifdef _DEBUG_ON

#define TRACELN(x) cout << " | DEBUG : " << x <<endl

#define TRACE(x) cout << " | DEBUG : " << x

#define TRACEA(x) cout << x

#define TRACELNA(x) cout << x <<endl

#else

#define TRACELN(x)

#define TRACE(x)

#define TRACEA(x)

#define TRACELNA(x)

#endif

//定义接口方法

#define METHOD(X) public: virtual HRESULT X

//定义IUnknown

DEFINEIID(IUnknown,0x010001);

INTERFACE IUnknown

{

METHOD(QueryInterface)(IID iid,void** ppv) = 0;

METHOD(AddRef)(void) = 0;

METHOD(Release)(void) = 0;

};

//定义IClassFactory

DEFINEIID(IClassFactory,0x347a24);

INTERFACE IClassFactory : public IUnknown

{

METHOD(CreateInstance)( IUnknown * pUnkOuter,

IID riid, void ** ppvObject) = 0;

METHOD(LockServer)(BOOL bLook) = 0;

};

//define class mapping entry struct

typedef HRESULT(* CreateFunc)(void* pv, IID riid, void** ppv);

typedef struct{

CLSID clsid;

CreateFunc pfnCreateObject;

CreateFunc pfnCreateInstance;

IUnknown* pCF; //类厂IUnknown

}_OBJECT_MAP_ENTRY;

#define DEFINECLSID(X,N) const CLSID_##X = N

#define BEGIN_OBJECT_MAP(x) static _OBJECT_MAP_ENTRY x[] = {

#define OBJECT_ENTRY(clsid,class) {clsid,class::_ClassFactory::CreateInstance, class::_CreatorObject::CreateInstance , NULL},

#define OBJECT_ENTRYEX(class) {CLSID_##class,class::_ClassFactory::CreateInstance, class::_CreatorObject::CreateInstance , NULL},

#define END_OBJECT_MAP() {0,NULL,NULL,NULL} };

//define Interface map entry struct

typedef struct{

IID iid;

DWORD dw;

}_INTERFACES_ENTRY;

//define interface mapping macro

#define BEGIN_INTERFACES_MAP(CN) public: typedef CN _ComClass; const static _INTERFACES_ENTRY* _GetInterfaceMap() { static _INTERFACES_ENTRY _Entry[] = { {IID_IUnknown,0},

#define INTERFACE_ENTRY(IN) {IID_##IN,offsetofclass(IN,_ComClass)},

#define END_INTERFACES_MAP() {0,0} }; return &_Entry[1]; } METHOD(QueryInterface)(IID iid,void** ppv) = 0; METHOD(AddRef)(void) = 0; METHOD(Release)(void) =0;

//类定义

template<typename T>

class CComObjectRoot

{

public:

METHOD(FinalAddRef)(void)

{

m_dwRef ++;

TRACE(" AddRef m_dwRef = ");

TRACELNA(m_dwRef);

return S_OK;

}

METHOD(FinalRelease)(void)

{

m_dwRef --;

ASSERT((m_dwRef >= 0));

TRACE(" Release m_dwRef = ");

TRACELNA(m_dwRef);

if(m_dwRef <= 0){

delete this;

TRACELN(" Delete ... ");

}

return S_OK;

}

METHOD(FinalQueryInterface)(void* pThis,IID iid,void** ppv)

{

ASSERT(pThis && iid);

const _INTERFACES_ENTRY* pEntry = T::_GetInterfaceMap();

ASSERT(pEntry);

while(!(pEntry->dw == 0 && pEntry->iid ==0))

{

if(iid == IID_IUnknown)

{

*ppv = (IUnknown*)((T*)pThis);

FinalAddRef();

TRACELN(" QueryInterface IUnknown ");

return S_OK;

}

if(iid == pEntry->iid){

*ppv = (void *)(((DWORD)pThis) + pEntry->dw);

FinalAddRef();

TRACELN(" QueryInterface OK");

return S_OK;

}

pEntry ++;

}

TRACELN(" QueryInterface Failed ");

return E_FAIL;

}

public:

CComObjectRoot()

{

m_dwRef = 0;

}

void SetVoid(void* pv){}

DWORD m_dwRef;

};

template<typename T>

class CComObject : public T

{

METHOD(QueryInterface)(IID iid,void** ppv)

{

return FinalQueryInterface(this,iid,ppv);

}

METHOD(AddRef)(void)

{

return FinalAddRef();

}

METHOD(Release)(void){

return FinalRelease();

}

};

class CComClassFactory :

public CComObjectRoot<CComClassFactory>,

public IClassFactory

{

METHOD(CreateInstance)(IUnknown* pUnkOuter , IID iid,

void** ppv)

{

return m_pfnCreateInstance(pUnkOuter ,

iid , ppv);

}

METHOD(LockServer)(BOOL bLock)

{

return S_OK;

}

void SetVoid(void* pv)

{

m_pfnCreateInstance = (CreateFunc )pv;

}

CreateFunc m_pfnCreateInstance;

BEGIN_INTERFACES_MAP(CComClassFactory)

INTERFACE_ENTRY(IClassFactory)

END_INTERFACES_MAP()

};

template<typename T>

class CComCreator

{

public:

static HRESULT CreateInstance(void* pv, IID riid, void** ppv)

{

ASSERT(riid);

T* p = new T;

if(p->QueryInterface(riid,ppv) != S_OK){

delete p;

return E_FAIL;

}

p->SetVoid(pv);

return S_OK;

}

};

#define DEFINE_CLASSFACTORY() typedef CComCreator< CComObject< CComClassFactory> > _ClassFactory;

#define DEFINE_OBJECT(x) typedef CComCreator< CComObject< x > > _CreatorObject;

template<typename T>

class CComCoClass

{

public:

DEFINE_CLASSFACTORY()

DEFINE_OBJECT(T)

};

class CComModule

{

public:

void Init(_OBJECT_MAP_ENTRY* p)

{

m_pObjectMap = p;

}

void Trim()

{

ASSERT(m_pObjectMap);

_OBJECT_MAP_ENTRY* pEntry = m_pObjectMap;

while(pEntry->clsid != NULL)

{

if(pEntry->pCF != NULL)

pEntry->pCF->Release();

pEntry ++;

}

}

_OBJECT_MAP_ENTRY* m_pObjectMap;

METHOD(GetClassObjcet)(CLSID clsid, IID riid, void** ppv)

{

ASSERT(m_pObjectMap);

_OBJECT_MAP_ENTRY* pEntry = m_pObjectMap;

while(pEntry->clsid != NULL)

{

if(pEntry->clsid == clsid)

{

if(pEntry->pCF == NULL){

HRESULT hRes = pEntry->pfnCreateObject(pEntry->pfnCreateInstance,

riid,(void**)&pEntry->pCF);

*ppv = (void *)pEntry->pCF;

return S_OK;

}

else

{

*ppv = (void *)pEntry->pCF;

return S_OK;

}

}

pEntry ++;

}

return E_FAIL;

}

};

//Test.cpp

#include "stdafx.h"

#include "atlmy.h"

DEFINEIID(IMy,0x34242);

INTERFACE IMy : public IUnknown

{

METHOD(F1)(void) = 0;

};

DEFINECLSID(MyClass,0x25346);

class MyClass :

public CComObjectRoot<MyClass>,

public CComCoClass<MyClass>,

public IMy

{

METHOD(F1)(void)

{

cout << "Hello" <<endl;

return S_OK;

}

BEGIN_INTERFACES_MAP(MyClass)

INTERFACE_ENTRY(IMy)

END_INTERFACES_MAP()

};

BEGIN_OBJECT_MAP(ObjectMap)

OBJECT_ENTRYEX(MyClass)

END_OBJECT_MAP()

CComModule _Module;

int main(int argc, char* argv[])

{

_Module.Init(ObjectMap);

IClassFactory *pCF = NULL;

IMy* pMy = NULL;

_Module.GetClassObjcet(CLSID_MyClass,IID_IClassFactory,(void**)&pCF);

pCF->CreateInstance(NULL,IID_IMy,(void** )&pMy);

IMy* pMy1 = NULL;

IClassFactory *pCF1 = NULL;

_Module.GetClassObjcet(CLSID_MyClass,IID_IClassFactory,(void**)&pCF1);

pCF1->CreateInstance(NULL,IID_IMy,(void** )&pMy1);

pMy1->F1();

pMy1->Release();

pMy->F1();

pMy->Release();

_Module.Trim();

return 0;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有