欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
MFC COM 筆記

MFC COM 筆記  

2011-03-13 17:40:18|  分類(lèi): COM |字號 訂閱

使用嵌套類(lèi)來(lái)實(shí)現接口 

例子:

class CDictionaryObj : public CCmdTarget

{

         DECLARE_DYNCREATE(CDictionaryObj)

         CDictionaryObj();

 

public:

         class XDictionary : public IDictionary

         {

         public:

                   virtual ULONG __stdcall AddRef();

                   virtual ULONG __stdcall Release();

                   virtual HRESULT __stdcall QueryInterface(REFIID iid, LPVOID* ppvObj);

                  

                   virtual BOOL __stdcall Initialize();

                   ......

         } m_xDictionary;

         friend class XDictionary;

 

protected:

         virtual ~CDictionaryObj();

         DECLARE_MESSAGE_MAP()

         DECLARE_INTERFACE_MAP()

         DECLARE_OLECREATE(CDictionaryObj)

};

 

效果和class CDictionaryObj : public IDictionary 一樣。因為對外部而言,使用QueryInterface來(lái)獲取接口指針,獲取IDictionary指針,相當于返回m_xDictionary的地址。然后就可以通過(guò)此指針來(lái)操作IDictionary提供的接口了。

 

上面的例子能夠看出CDictionaryObj 并沒(méi)有實(shí)現QueryInterface, AddRef, Release函數。這是因為他繼承于CCmdTarget,CCmdTarget已經(jīng)實(shí)現了。而且它的實(shí)現還可以調用到內部類(lèi)的三個(gè)接口函數。

 

CCmdTarget提供的消息機制中,使用了靜態(tài)映射表(消息ID和處理函數在WinMain執行之前,就已經(jīng)建立好對應關(guān)系了)。同樣,COM機制中使用接口映射表。


 

代碼

DECLARE_INTERFACE_MAP()

private:

static const AFX_INTERFACEMAP_ENTRY _interfaceEntries[];

protected:

static AFX_DATA const AFX_INTERFACEMAP interfaceMap;

static const AFX_INTERFACEMAP* PASCAL _GetBaseInterfaceMap();

virtual const AFX_INTERFACEMAP* GetInterfaceMap() const;

struct AFX_INTERFACEMAP_ENTRY

struct AFX_INTERFACEMAP_ENTRY {

const void* piid; // the interface id (IID) (NULL for aggregate)

size_t nOffset;  // offset of the interface vtable from m_unknown

};

struct AFX_INTERFACEMAP

struct AFX_INTERFACEMAP {

 // NULL is root class

const AFX_INTERFACEMAP* (PASCAL* pfnGetBaseMap)();

// map for this class

const AFX_INTERFACEMAP_ENTRY* pEntry;

};

BEGIN_INTERFACE_MAP(theClass, theBase)

const AFX_INTERFACEMAP* PASCAL theClass::_GetBaseInterfaceMap()

       { return &theBase::interfaceMap; }

const AFX_INTERFACEMAP* theClass::GetInterfaceMap() const

       { return &theClass::interfaceMap; }

AFX_COMDAT const AFX_DATADEF AFX_INTERFACEMAP theClass::interfaceMap =

       { &theClass::_GetBaseInterfaceMap, &theClass::_interfaceEntries[0], };

AFX_COMDAT const AFX_DATADEF AFX_INTERFACEMAP_ENTRY theClass::_interfaceEntries[] =

{

INTERFACE_PART(theClass, iid, localClass)

{ &iid, offsetof(theClass, m_x##localClass) },

END_INTERFACE_MAP()

         { NULL, (size_t)-1 }

};

DECLARE_OLECREATE(class_name)

public:

         static AFX_DATA COleObjectFactory factory;

         static AFX_DATA const GUID guid;

IMPLEMENT_OLECREATE(class_name, external_name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)

AFX_DATADEF COleObjectFactory class_name::factory(class_name::guid, RUNTIME_CLASS(class_name), FALSE, _T(external_name));

AFX_COMDAT const AFX_DATADEF GUID class_name::guid =

{ l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } };

 

說(shuō)明: _interfaceEntries[] 保存了AFX_INTERFACEMAP_ENTRY 數組,這個(gè)數組也就是接口ID和接口vtable與父類(lèi)指針的偏移量的映射表。interfaceMap 其中一個(gè)指針指向父類(lèi),另外一個(gè)指向_interfaceEntries[]。_GetBaseInterfaceMap函數返回interfaceMap的地址。這張映射表的實(shí)現是通過(guò)BEGIN_INTERFACE_MAP(theClass, theBase), INTERFACE_PART(theClass, iid, localClass), END_INTERFACE_MAP() 三個(gè)宏實(shí)現的。

 

CCmdTarget 實(shí)現了倆個(gè)版本的IUnkown,非委托、委托IUnkown。

 

CCmdTarget繼承下來(lái)的,為了實(shí)現聚合,調用的應該是委托IUnkown接口(External)。

目前為止,只有接口的實(shí)現,沒(méi)有出現類(lèi)廠(chǎng),類(lèi)廠(chǎng)已經(jīng)被MFC自動(dòng)生成了。

 

DLL AppWizard向導中選中:Automation,向導會(huì )生成如下代碼:

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)

{

         AFX_MANAGE_STATE(AfxGetStaticModuleState());

         return AfxDllGetClassObject(rclsid, riid, ppv);

}

 

STDAPI DllCanUnloadNow(void)

{

         AFX_MANAGE_STATE(AfxGetStaticModuleState());

         return AfxDllCanUnloadNow();

}

 

// by exporting DllRegisterServer, you can use regsvr.exe

STDAPI DllRegisterServer(void)

{

         AFX_MANAGE_STATE(AfxGetStaticModuleState());

         COleObjectFactory::UpdateRegistryAll();

         return S_OK;

}

 

我們知道,類(lèi)廠(chǎng)應該是DllGetClassObject里面創(chuàng )建的,這個(gè)函數調用了AfxDllGetClassObject。秘密就在其后。

 

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;

}

 

MFC使用的就是COleObjectFactory 這個(gè)通用的類(lèi)廠(chǎng)(Ole是歷史原因導致的,其實(shí)CComObjectFactory更加合適)。

COleObjectFactory CCmdTarget派生,實(shí)現了IClassFactory2接口。此類(lèi)廠(chǎng)使用MFC動(dòng)態(tài)創(chuàng )建機制(DECLARE_DYNCREATE),創(chuàng )建對象。那么如何將此類(lèi)廠(chǎng)和某個(gè)類(lèi)關(guān)聯(lián)?使用DECLARE_OLECREATE,IMPLEMENT_OLECREATE。他們將類(lèi)的CLSID和類(lèi)的RUNTIME信息傳遞給CComObjectFactory類(lèi)廠(chǎng)。這樣類(lèi)廠(chǎng)就能使用CLSID和動(dòng)態(tài)信息進(jìn)行創(chuàng )建對象了。那么類(lèi)廠(chǎng)是如何被Afx找到的呢。從代碼中看出,類(lèi)廠(chǎng)指針的是從模塊信息里面的類(lèi)廠(chǎng)鏈來(lái)獲取的。而類(lèi)廠(chǎng)構造函數中調用了pModuleState->m_factoryList.AddHead(this); 將自己的信息加入模塊信息里面,模塊信息是全局的變量。這樣就跑通了。流程如下:

AfxDllGetClassObject ->

Module State (factoryList), look up Factory’s clsid. ->

Get IClassFactory2 reference ->

CreateInstance ->

Dynamic create object using Dynamic information. ->

Finish.

 

What should we do?

VC++ 6.0 提供了MFCATL兩套庫,用來(lái)開(kāi)發(fā)COM。 

這里使用MFC

1. 使用AppWizard生產(chǎn)MFC exe/dll, 選擇Automation

2. 定義接口

3. 繼承CCmdTarget,實(shí)現接口,(嵌入式)BEGIN_INTERFACE_PART, INIT_INTERFACE_PART, STDMETHOD, STDMETHOD_, END_INTERFACE_PART.

4. 定義各個(gè)接口函數體:Class::XlocalClass::AddRef/Release/QueryInterface(), 實(shí)現接口的各個(gè)接口

5. 定義類(lèi)的靜態(tài)信息,DECLARE_INTERFACE_MAP,實(shí)現使用:BEGIN_INTERFACE_MAP, INTERFACE_PART, END_INTERFACE_MAP

6. 使用MFC類(lèi)廠(chǎng),類(lèi)里面使用:DECLARE_OLECREATE, 實(shí)現使用 IMPLEMENT_OLECREATE
轉發(fā)至微博
0  分享到:        
閱讀(338)| 評論(0)| 轉載 (0) |舉報
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
消息映射和命令傳遞(轉)
CodeGuru: Simulating Multiple Inheritance Und...
MFC的消息映射機制揭秘
MFC消息響應機制及映射機制理解
在函數前加Afx和::以及函數后加const的意義
C宏——智者的利刃,愚者的惡夢(mèng)!
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久