• 一个用MFC实现Com聚合样本


    ComATLATLMFCMFC MFCIUnknownMFCCCmdTargetComMFCCom MFCCOM

    1.

    1.1

    #pragma  once
    
    
    typedef long HRESULT;
    
    // {30DF3430-0266-11cf-BAA6-00AA003E0EED}
    extern const GUID CLSID_Math;
    //{ 0x30df3430, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed } };
    
    //////////////////////////////////////////////////////////////////////////////////////
    
    // {30DF3432-0266-11cf-BAA6-00AA003E0EED}
    extern const GUID IID_IOPerator;
    //{ 0x30df3432, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed } };
    
    class IOPerator:public IUnknown
    {
    public:
    
    	virtual HRESULT _stdcall Add(int nParam1, int nParam2, int* pResult) =0;
    	virtual HRESULT _stdcall Subtract(int nParam1, int nParam2, int* pResult) =0;
    	virtual HRESULT _stdcall Multiple(int nParam1, int nParam2, int* pResult) =0;
    	virtual HRESULT _stdcall Divide(int nParam1, int nParam2, int* pResult) =0;
    };
    
    
    // {30DF3433-0266-11cf-BAA6-00AA003E0EED}
    extern const GUID IID_IAdvanceOPerator;
    //{ 0x30df3433, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed } };
    
    class IAdvanceOPerator:public IUnknown
    {
    public:
    
    	virtual HRESULT _stdcall Abs(int nParam1, int* pResult) =0;
    	virtual HRESULT _stdcall Power(int nParam1, int nParam2, int* pResult) =0;
    };
    // CMyMath command target
    
    class CMyMath : public CCmdTarget
    {
    	DECLARE_DYNCREATE(CMyMath)
    
    public:
    	CMyMath();
    	virtual ~CMyMath();
    
    	virtual void OnFinalRelease();
    
    protected:
    	DECLARE_OLECREATE(CMyMath)
    	DECLARE_MESSAGE_MAP()
    	DECLARE_DISPATCH_MAP()
    
    	DECLARE_INTERFACE_MAP()
    	BEGIN_INTERFACE_PART(OPerator, IOPerator) 
    		STDMETHOD_(HRESULT, Add)(int nParam1, int nParam2, int* pResult);
    		STDMETHOD_(HRESULT, Subtract)(int nParam1, int nParam2, int* pResult);
    		STDMETHOD_(HRESULT, Multiple)(int nParam1, int nParam2, int* pResult);
    		STDMETHOD_(HRESULT, Divide)(int nParam1, int nParam2, int* pResult);
    	END_INTERFACE_PART(OPerator)
    
    	BEGIN_INTERFACE_PART(AdvanceOperator, IAdvanceOPerator)  
    		STDMETHOD_(HRESULT, Abs)(int nParam1, int* pResult);
    		STDMETHOD_(HRESULT, Power)(int nParam1, int nParam2, int* pResult);
    	END_INTERFACE_PART(AdvanceOperator) 
    };
    
    


    1.2

    #include "stdafx.h"
    #include "MyCom16.h"
    #include "MyMath.h"
    
    
    // CMyMath
    
    IMPLEMENT_DYNCREATE(CMyMath, CCmdTarget)
    
    
    CMyMath::CMyMath()
    {
    	EnableAutomation();
    	EnableAggregation();
    }
    
    CMyMath::~CMyMath()
    {
    }
    
    
    void CMyMath::OnFinalRelease()
    {
    	// When the last reference for an automation object is released
    	// OnFinalRelease is called.  The base class will automatically
    	// deletes the object.  Add additional cleanup required for your
    	// object before calling the base class.
    
    	CCmdTarget::OnFinalRelease();
    }
    
    
    BEGIN_MESSAGE_MAP(CMyMath, CCmdTarget)
    END_MESSAGE_MAP()
    
    
    BEGIN_DISPATCH_MAP(CMyMath, CCmdTarget)
    END_DISPATCH_MAP()
    
    // Note: we add support for IID_IMyMath to support typesafe binding
    //  from VBA.  This IID must match the GUID that is attached to the 
    //  dispinterface in the .IDL file.
    
    // {7259EA0F-0E64-4FF9-BBA1-332E82AFA0D3}
    static const IID IID_IMyMath =
    { 0x7259EA0F, 0xE64, 0x4FF9, { 0xBB, 0xA1, 0x33, 0x2E, 0x82, 0xAF, 0xA0, 0xD3 } };
    static const GUID IID_IOPerator = 
    { 0x30df3432, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed }};
    
    static const GUID IID_IAdvanceOPerator = 
    { 0x30df3433, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed }};
    
    // CLSID_Math
    IMPLEMENT_OLECREATE(CMyMath, "MyCom16.MyMath", 0x30df3430, 0x266, 0x11cf,  0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed)
    
    BEGIN_INTERFACE_MAP(CMyMath, CCmdTarget)
    	INTERFACE_PART(CMyMath,IID_IMyMath, Dispatch)
    	INTERFACE_PART(CMyMath,IID_IOPerator,OPerator)
    	INTERFACE_PART(CMyMath,IID_IAdvanceOPerator,AdvanceOperator)
    END_INTERFACE_MAP()
    
    
    // CMyMath message handlers
    
    ULONG  CMyMath::XOPerator::AddRef()
    {
    	METHOD_PROLOGUE(CMyMath, OPerator);  
    	return pThis->ExternalAddRef();
    
    }
    ULONG  CMyMath::XOPerator::Release()
    {
    	METHOD_PROLOGUE(CMyMath, OPerator);  
    	return pThis->ExternalRelease();
    
    }
    
    HRESULT  CMyMath::XOPerator::QueryInterface(REFIID riid, void** ppObject)
    {
    	METHOD_PROLOGUE_EX_(CMyMath, OPerator);
    	return pThis->ExternalQueryInterface((void *)&riid,ppObject);
    }
    
    HRESULT  CMyMath::XOPerator::Add( int nParam1, int nParam2, int* pResult )
    {
    	*pResult = nParam1 + nParam2;
    	return S_OK;
    }
    
    HRESULT  CMyMath::XOPerator::Subtract( int nParam1, int nParam2, int* pResult )
    {
    	*pResult = nParam1 - nParam2;
    	return S_OK;
    }
    
    HRESULT  CMyMath::XOPerator::Multiple( int nParam1, int nParam2, int* pResult )
    {
    	*pResult = nParam1 * nParam2;
    	return S_OK;
    }
    
    HRESULT  CMyMath::XOPerator::Divide( int nParam1, int nParam2, int* pResult )
    {
    	*pResult = nParam1 / nParam2;
    	return S_OK;
    }
    
    ULONG  CMyMath::XAdvanceOperator::AddRef()
    {
    	METHOD_PROLOGUE(CMyMath, AdvanceOperator);  
    	return pThis->ExternalAddRef();
    
    }
    ULONG  CMyMath::XAdvanceOperator::Release()
    {
    	METHOD_PROLOGUE(CMyMath, AdvanceOperator);  
    	return pThis->ExternalRelease();
    
    }
    
    HRESULT  CMyMath::XAdvanceOperator::QueryInterface(REFIID riid, void** ppObject)
    {
    	METHOD_PROLOGUE(CMyMath, AdvanceOperator);  
    	return pThis->ExternalQueryInterface((void *)&riid,ppObject);
    }
    
    HRESULT _stdcall CMyMath::XAdvanceOperator::Abs( int nParam1, int* pResult )
    {
    	if(nParam1 < 0)
    		*pResult = -nParam1;
    	else
    		*pResult = nParam1;
    	return S_OK;
    }
    
    HRESULT _stdcall CMyMath::XAdvanceOperator::Power( int nParam1, int nParam2, int* pResult )
    {
    	*pResult =1;
    	for(int i=0;i<nParam2;i++)
    		*pResult *=nParam1;
    	return S_OK;
    }

    2

    2.1

    #pragma  once
    
    
    typedef long HRESULT;
    
    
    class IArea:public IUnknown
    {
    public:
    
    	virtual HRESULT _stdcall Triangle(int width, int High, float* pResult) =0;
    	virtual HRESULT _stdcall Square(int lengh, float* pResult) =0;
    	virtual HRESULT _stdcall Cirle(int r, float* pResult) =0;
    };


    #pragma once
    #include "IArea.h"
    
    // CMyMath2 command target
    
    class CMyMath2 : public CCmdTarget
    {
    	DECLARE_DYNCREATE(CMyMath2)
    
    public:
    	CMyMath2();
    	virtual ~CMyMath2();
    
    	virtual void OnFinalRelease();
        virtual BOOL OnCreateAggregates();
    
    	BEGIN_INTERFACE_PART(Area, IArea)  
    		STDMETHOD_(HRESULT, Triangle)(int width, int High, float* pResult);
    		STDMETHOD_(HRESULT, Square)(int lengh, float* pResult);
    		STDMETHOD_(HRESULT, Cirle)(int r, float* pResult);
    	END_INTERFACE_PART(Area) 
    protected:
    	DECLARE_OLECREATE(CMyMath2)
    	DECLARE_MESSAGE_MAP()
    	DECLARE_DISPATCH_MAP()
    	DECLARE_INTERFACE_MAP()
    
    };
    

    2.2

    #include "MyMath2.h"
    
    #include <iostream>
    using namespace std;
    
    const float PI = 3.14;
    static const GUID CLSID_Math =
    { 0x30df3430, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed } };
    
    
    // CMyMath2
    IMPLEMENT_DYNCREATE(CMyMath2, CCmdTarget)
    
    
    CMyMath2::CMyMath2()
    {
    	EnableAutomation();
    	
    }
    
    CMyMath2::~CMyMath2()
    {
    }
    
    
    void CMyMath2::OnFinalRelease()
    {
    	// When the last reference for an automation object is released
    	// OnFinalRelease is called.  The base class will automatically
    	// deletes the object.  Add additional cleanup required for your
    	// object before calling the base class.
        if(m_xInnerUnknown !=NULL)
    	{
    		IUnknown *pUnk =(IUnknown *)m_xInnerUnknown;
    		pUnk->Release();
    	}
    	CCmdTarget::OnFinalRelease();
    }
    
    
    BEGIN_MESSAGE_MAP(CMyMath2, CCmdTarget)
    END_MESSAGE_MAP()
    
    
    BEGIN_DISPATCH_MAP(CMyMath2, CCmdTarget)
    END_DISPATCH_MAP()
    
    // Note: we add support for IID_IMyMath2 to support typesafe binding
    //  from VBA.  This IID must match the GUID that is attached to the 
    //  dispinterface in the .IDL file.
    
    // {60B1DE57-1DE8-4759-B220-C35E03B2049D}
    static const IID IID_IMyMath2 =
    { 0x60B1DE57, 0x1DE8, 0x4759, { 0xB2, 0x20, 0xC3, 0x5E, 0x3, 0xB2, 0x4, 0x9D } };
    
    static const GUID IID_IArea = 
    { 0x30df3452, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed }};
    
    
    // CLSID_Math
    IMPLEMENT_OLECREATE(CMyMath2, "MyCom9.MyMath2", 0x30df3450, 0x266, 0x11cf,  0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed)
    
    BEGIN_INTERFACE_MAP(CMyMath2, CCmdTarget)
    	INTERFACE_PART(CMyMath2, IID_IMyMath2, Dispatch)
    	INTERFACE_PART(CMyMath2,IID_IArea,Area)
    	INTERFACE_AGGREGATE(CMyMath2,m_xInnerUnknown) //CMyMath2CMyMath
    END_INTERFACE_MAP()
    
    
    //CMyMath2CMyMath
    BOOL CMyMath2::OnCreateAggregates()
    {
    #if 0
    	//
    	::CoCreateInstance(CLSID_Math,(IUnknown *)this,CLSCTX_INPROC_SERVER,IID_IUnknown,(void **)&m_xInnerUnknown);
    #else
    	LPUNKNOWN pUnk = GetControllingUnknown();
    	::CoCreateInstance(CLSID_Math,(IUnknown *)pUnk,CLSCTX_INPROC_SERVER,IID_IUnknown,(void **)&m_xInnerUnknown);
    #endif
    	return TRUE;
    }
    
    
    // CMyMath2 message handlers
    HRESULT _stdcall CMyMath2::XArea::Triangle( int width, int High, float* pResult )
    {
    	*pResult =width*High *1.0/2;
    	return S_OK;
    }
    
    HRESULT _stdcall CMyMath2::XArea::Square( int lengh, float* pResult )
    {
    	*pResult =lengh *lengh*1.0/2;
    	return S_OK;
    }
    
    HRESULT _stdcall CMyMath2::XArea::Cirle( int r, float* pResult )
    {
    	*pResult = PI *r*r;
    	return S_OK;
    }
    
    ULONG  CMyMath2::XArea::AddRef()
    {
    	METHOD_PROLOGUE(CMyMath2, Area);  
    	return pThis->ExternalAddRef();
    
    }
    
    ULONG  CMyMath2::XArea::Release()
    {
    	METHOD_PROLOGUE(CMyMath2, Area);  
    	return pThis->ExternalRelease();
    }
    
    HRESULT  CMyMath2::XArea::QueryInterface(REFIID riid, void** ppObject)
    {
    	METHOD_PROLOGUE_EX_(CMyMath2, Area);
    	return pThis->ExternalQueryInterface((void *)&riid,ppObject);;
    }

    3.

    #include "../MyCom16/Operator.h"
    #include "../MyCom9/IArea.h"
    
    using namespace std;
    
    
    static const GUID CLSID_Math =
    { 0x30df3430, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed } };
    
    
    static const GUID IID_IOPerator =
    { 0x30df3432, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed } };
    
    static const GUID IID_IAdvanceOPerator =
    { 0x30df3433, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed } };
    
    static const GUID CLSID_Math2 = 
    { 0x30df3450, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed }};
    
    static const GUID IID_IArea = 
    { 0x30df3452, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed }};
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	CLSID clsId;
    	IClassFactory *pMathFactory = NULL;
    	IUnknown* pUnknown = NULL;
    	IUnknown* pUnk = NULL;
    	IOPerator *pOPerator = NULL;
    	IAdvanceOPerator *pAdvanceOperator = NULL;
    	IArea   *pArea = NULL;
    	IArea   *pArea2 = NULL;
    	IAdvanceOPerator *pAdvanceOperator2 = NULL;
    	int nResult = 0;
    	HRESULT hRes;
    
    	CoInitialize(NULL);
    
     ///////////////////////Test MyCom1///////////////////////////////////////////////////////////////////
    #if 1
    	//CLSIDFromProgID(_T("Testcom1 Server"),&clsId);
    	hRes = CoGetClassObject(CLSID_Math, CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pMathFactory);
    	if(FAILED(hRes))
    	{
    		return 0;
    	}
    	pMathFactory->CreateInstance(NULL,IID_IOPerator,(void **)&pOPerator);
    	pMathFactory->Release();
    
    	pOPerator->Add(5,6,&nResult);
        cout<<"5+6 ="<<nResult<<endl;
    	pOPerator->Multiple(5,6,&nResult);
    	cout<<"5*6 ="<<nResult<<endl;
    	pOPerator->Divide(5,6,&nResult);
    	cout<<"5/6 ="<<nResult<<endl;
        
    	pOPerator->QueryInterface(IID_IAdvanceOPerator,(void **)&pAdvanceOperator);
    	pAdvanceOperator->Abs(-123,&nResult);
        cout<<"Abs(-123)  ="<<nResult<<endl;
    	pAdvanceOperator->Power(5,3,&nResult);
    	cout<<"Power(5,3) ="<<nResult<<endl;
    
        pAdvanceOperator->QueryInterface(IID_IUnknown,(void **)&pUnknown);
    	pOPerator->QueryInterface(IID_IUnknown,(void **)&pUnk);
        pUnk->QueryInterface(IID_IAdvanceOPerator,(void **)&pAdvanceOperator2);
        if(pUnk == pUnknown)
    		cout<<"They are the same com obj"<<endl;
    	else
    		cout<<"They not equal obj" <<endl;
    
    	pUnknown->Release();
    	pUnk->Release();
    	pAdvanceOperator->Release();
    	pOPerator->Release();
    	pAdvanceOperator2->Release();
    
    	pOPerator = NULL;
    	pAdvanceOperator = NULL;
    	pUnk = NULL;
    	pUnknown = NULL;
    	pAdvanceOperator2 =NULL;
    #endif
    
    	/*
    	 
    	 Com9 Com1
    	*/
    #if 1
    	pOPerator = NULL;
    	pAdvanceOperator = NULL;
    	pUnk =NULL;
    	pUnknown = NULL;
    	//CLSIDFromProgID(_T("Testcom1 Server"),&clsId);
    	hRes = CoGetClassObject(CLSID_Math2, CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pMathFactory);
    	if(FAILED(hRes))
    	{
    		return 0;
    	}
    	pMathFactory->CreateInstance(NULL,IID_IArea,(void **)&pArea);
    	pMathFactory->Release();
        float fResult =0.0f;
    	pArea->Triangle(3,4,&fResult);
    	cout<<"Triangle(3,4) = "<<fResult<<endl;
    
    	pArea->Cirle(5,&fResult);
    	cout<<"Cirle(5) = "<<fResult<<endl;
        pArea->QueryInterface(IID_IOPerator,(void **)&pOPerator);
    	pOPerator->Add(5,6,&nResult);
    	cout<<"5+6 ="<<nResult<<endl;
    	pOPerator->Multiple(5,6,&nResult);
    	cout<<"5*6 ="<<nResult<<endl;
    	pOPerator->Divide(5,6,&nResult);
    	cout<<"5/6 ="<<nResult<<endl;
    
        pOPerator->QueryInterface(IID_IAdvanceOPerator,(void **)&pAdvanceOperator);
    	pAdvanceOperator->QueryInterface(IID_IArea,(void **)&pArea2);
    
    	if(pArea == pArea2)
    		cout<<"They are the same com obj"<<endl;
    	else
    		cout<<"They not equal obj" <<endl;
    
    
    	pArea->QueryInterface(IID_IUnknown,(void **)&pUnknown);
    	pOPerator->QueryInterface(IID_IUnknown,(void **)&pUnk);
    	if(pUnk ==pUnknown)
    		cout<<"They are the same com obj"<<endl;
    	else
    		cout<<"They not equal obj" <<endl;
    
    	pUnknown->Release();
    	pUnk->Release();
    	pArea->Release();
    	pOPerator->Release();
    	pAdvanceOperator->Release();
    	pArea2->Release();
    #endif
    
    	::CoUninitialize();
    	return 0;
    }
    


  • 相关阅读:
    Git使用教程
    H5项目常见问题汇总及解决方案
    globalAlpha 示例
    canvas 绘制三次贝塞尔曲线
    canvas 绘制二次贝塞尔曲线
    html5 图片360旋转
    HTML5 arc的例子
    HTML5 绘制阴影
    HTML5 canvas绘制文本
    html5 lineTo的使用例子
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4556041.html
Copyright © 2020-2023  润新知