用MFC实现COM

来源:互联网 发布:红包随机分配算法 编辑:程序博客网 时间:2024/05/21 14:45

1.建立常规DLL(附加功能里面选择自动化选项)

2.创建接口并提供相应的IID

struct  IMotion:public IUnknown{

    STDMETHOD_(void,Fly)()PURE;

    STDMETHOD_(int&,GetPosition)()PURE;

};

struct IVisual:public IUnknown {

    STDMETHOD_(void,Display)()PURE;

};

// {B6169E5C-6AC9-403e-ADE4-5CF575A645EB}

static const IID IID_IMotion =

{ 0xb6169e5c, 0x6ac9, 0x403e, { 0xad, 0xe4, 0x5c, 0xf5, 0x75, 0xa6, 0x45, 0xeb } };

 

// {EDD32B47-5930-4d45-9181-5ABECD138CAC}

static const IID IID_IVisual =

{ 0xedd32b47, 0x5930, 0x4d45, { 0x91, 0x81, 0x5a, 0xbe, 0xcd, 0x13, 0x8c, 0xac } };

3.创建COM(自动化选项里面选择可按类型ID创建”)

4.添加接口定义:,CCmdTarget派生

COM类定义中添加接口

BEGIN_INTERFACE_PART(Motion,IMotion)

       STDMETHOD_(void,Fly)();

       STDMETHOD_(int&,GetPosition)();

END_INTERFACE_PART(Motion)

 

 

    BEGIN_INTERFACE_PART(Visual,IVisual)

       STDMETHOD_(void,Display)();

    END_INTERFACE_PART(Visual)

 

COM类实现文件里面添加接口映射表

BEGIN_INTERFACE_MAP(CSpaceship, CCmdTarget)

    INTERFACE_PART(CSpaceship, IID_ISpaceship, Dispatch)

    INTERFACE_PART(CSpaceship,IID_IMotion,Motion)

    INTERFACE_PART(CSpaceship,IID_IVisual,Visual)

END_INTERFACE_MAP()

   

5.处理接口函数:(以下三个函数是所有接口都要实现的)

  (获取pThis  METHOD_PROLOGUE(CSpaceship, Motion))

STDMETHODIMP_(ULONG) CSpaceship::XMotion::AddRef()

{

    TRACE("CSpaceship::XMotion::AddRef/n");

    METHOD_PROLOGUE(CSpaceship, Motion)

        return pThis->ExternalAddRef();

}

STDMETHODIMP_(ULONG) CSpaceship::XMotion::Release()

{

    TRACE("CSpaceship::XMotion::Release/n");

    METHOD_PROLOGUE(CSpaceship, Motion)

        return pThis->ExternalRelease();

}

STDMETHODIMP CSpaceship::XMotion::QueryInterface(REFIID iid, LPVOID* ppvObj)

{

    ITrace(iid, "CSpaceship::XMotion::QueryInterface");

    METHOD_PROLOGUE(CSpaceship, Motion)

        return pThis->ExternalQueryInterface(&iid, ppvObj);

}

 

 

 

 

以下为客户端实现

1..添加COM支持

添加头文件      #include<afxole.h>

初始化COM通信: ::CoInitialize(NULL);

所有代码:

服务器端:

//Interface.h

struct  IMotion:public IUnknown{

    STDMETHOD_(void,Fly)()PURE;

    STDMETHOD_(int&,GetPosition)()PURE;

};

struct IVisual:public IUnknown {

    STDMETHOD_(void,Display)()PURE;

};

// {B6169E5C-6AC9-403e-ADE4-5CF575A645EB}

static const IID IID_IMotion =

{ 0xb6169e5c, 0x6ac9, 0x403e, { 0xad, 0xe4, 0x5c, 0xf5, 0x75, 0xa6, 0x45, 0xeb } };

 

// {EDD32B47-5930-4d45-9181-5ABECD138CAC}

static const IID IID_IVisual =

{ 0xedd32b47, 0x5930, 0x4d45, { 0x91, 0x81, 0x5a, 0xbe, 0xcd, 0x13, 0x8c, 0xac } };

 

 

 

 

//Spaceship.h头文件

#pragma once

 

#include "Interface.h"

// CSpaceship 命令目标

void ITrace(REFIID iid, const char* str);

class CSpaceship : public CCmdTarget

{

    DECLARE_DYNCREATE(CSpaceship)

private:

    int m_nPosition;

    int m_nAcceleration;

    int m_nColor;

 

public:

    CSpaceship();

    virtual ~CSpaceship();

 

    virtual void OnFinalRelease();

 

protected:

    DECLARE_MESSAGE_MAP()

    DECLARE_OLECREATE(CSpaceship)

    DECLARE_DISPATCH_MAP()

    DECLARE_INTERFACE_MAP()

 

 

    //以下为手动添加

    BEGIN_INTERFACE_PART(Motion,IMotion)

        STDMETHOD_(void,Fly)();

        STDMETHOD_(int&,GetPosition)();

    END_INTERFACE_PART(Motion)

 

 

    BEGIN_INTERFACE_PART(Visual,IVisual)

        STDMETHOD_(void,Display)();

    END_INTERFACE_PART(Visual)

 

 

};

 

 

// Spaceship.cpp : 实现文件

//

 

#include "stdafx.h"

#include "Ex22b.h"

#include "Spaceship.h"

 

 

// CSpaceship

 

IMPLEMENT_DYNCREATE(CSpaceship, CCmdTarget)

CSpaceship::CSpaceship()

{

    EnableAutomation();

   

    // 为了使应用程序在 OLE 自动化对象处于活动状态时保持

    //  运行,构造函数调用 AfxOleLockApp

    TRACE("CSpaceship/n");

    m_nAcceleration=101;

    m_nPosition=100;

    m_nColor=102;

   

    AfxOleLockApp();

}

 

CSpaceship::~CSpaceship()

{

    // 为了在用 OLE 自动化创建所有对象后终止应用程序,

    // 析构函数调用 AfxOleUnlockApp

    TRACE("~Spaceship/n");

   

    AfxOleUnlockApp();

}

 

 

void CSpaceship::OnFinalRelease()

{

    // 释放了对自动化对象的最后一个引用后,将调用

    // OnFinalRelease。基类将自动

    // 删除该对象。在调用该基类之前,请添加您的

    // 对象所需的附加清除代码。

 

    CCmdTarget::OnFinalRelease();

}

 

 

BEGIN_MESSAGE_MAP(CSpaceship, CCmdTarget)

END_MESSAGE_MAP()

 

 

BEGIN_DISPATCH_MAP(CSpaceship, CCmdTarget)

END_DISPATCH_MAP()

 

// 注意: 我们添加 IID_ISpaceship 支持

//以支持来自 VBA 的类型安全绑定。此 IID 必须同附加到 .IDL 文件中的

//调度接口的 GUID 匹配。

 

// {1DE882B0-C6AE-4DFF-9F3F-E02E4D9D613E}

static const IID IID_ISpaceship =

{ 0x1DE882B0, 0xC6AE, 0x4DFF, { 0x9F, 0x3F, 0xE0, 0x2E, 0x4D, 0x9D, 0x61, 0x3E } };

 

BEGIN_INTERFACE_MAP(CSpaceship, CCmdTarget)

    INTERFACE_PART(CSpaceship, IID_ISpaceship, Dispatch)

    INTERFACE_PART(CSpaceship,IID_IMotion,Motion)       //手动添加

    INTERFACE_PART(CSpaceship,IID_IVisual,Visual)       //手动添加

END_INTERFACE_MAP()

 

// {E9BA3078-5EC5-4A65-B805-9C341D6DF00A}

IMPLEMENT_OLECREATE_FLAGS(CSpaceship, "Ex22b.Spaceship", afxRegApartmentThreading, 0xe9ba3078, 0x5ec5, 0x4a65, 0xb8, 0x5, 0x9c, 0x34, 0x1d, 0x6d, 0xf0, 0xa)

 

 

// CSpaceship 消息处理程序

//以下为手动添加

STDMETHODIMP_(ULONG) CSpaceship::XMotion::AddRef()

{

    TRACE("CSpaceship::XMotion::AddRef/n");

    METHOD_PROLOGUE(CSpaceship, Motion)

        return pThis->ExternalAddRef();

}

STDMETHODIMP_(ULONG) CSpaceship::XMotion::Release()

{

    TRACE("CSpaceship::XMotion::Release/n");

    METHOD_PROLOGUE(CSpaceship, Motion)

        return pThis->ExternalRelease();

}

STDMETHODIMP CSpaceship::XMotion::QueryInterface(REFIID iid, LPVOID* ppvObj)

{

    ITrace(iid, "CSpaceship::XMotion::QueryInterface");

    METHOD_PROLOGUE(CSpaceship, Motion)

        return pThis->ExternalQueryInterface(&iid, ppvObj);

}

STDMETHODIMP_(void) CSpaceship::XMotion::Fly()

{

    TRACE("CSpaceship::XMotion::Fly/n");

    METHOD_PROLOGUE(CSpaceship, Motion)

        TRACE("m_nPosition = %d/n", pThis->m_nPosition);

    TRACE("m_nAcceleration = %d/n", pThis->m_nAcceleration);

    return;

}

STDMETHODIMP_(int&) CSpaceship::XMotion::GetPosition()

{

    TRACE("CSpaceship::XMotion::GetPosition/n");

    METHOD_PROLOGUE(CSpaceship, Motion)

        TRACE("m_nPosition = %d/n", pThis->m_nPosition);

    TRACE("m_nAcceleration = %d/n", pThis->m_nAcceleration);

    return pThis->m_nPosition;

}

 

STDMETHODIMP_(ULONG) CSpaceship::XVisual::AddRef()

{

    TRACE("CSpaceship::XVisual::AddRef/n");

    METHOD_PROLOGUE(CSpaceship, Visual)

        return pThis->ExternalAddRef();

}

 

STDMETHODIMP_(ULONG) CSpaceship::XVisual::Release()

{

    TRACE("CSpaceship::XVisual::Release/n");

    METHOD_PROLOGUE(CSpaceship, Visual)

        return pThis->ExternalRelease();

}

 

STDMETHODIMP CSpaceship::XVisual::QueryInterface(

    REFIID iid, LPVOID* ppvObj)

{

    ITrace(iid, "CSpaceship::XVisual::QueryInterface");

    METHOD_PROLOGUE(CSpaceship, Visual)

        return pThis->ExternalQueryInterface(&iid, ppvObj);

}

 

STDMETHODIMP_(void) CSpaceship::XVisual::Display()

{

    TRACE("CSpaceship::XVisual::Display/n");

    METHOD_PROLOGUE(CSpaceship, Visual)

        TRACE("m_nPosition = %d/n", pThis->m_nPosition);

    TRACE("m_nColor = %d/n", pThis->m_nColor);

}

 

 

void ITrace(REFIID iid, const char* str)

{

    OLECHAR* lpszIID;

    ::StringFromIID(iid, &lpszIID);

    CString strTemp(lpszIID);

    TRACE("%s - %s/n", (const char*) strTemp, (const char*) str);

    AfxFreeTaskMem(lpszIID);

}

 

 

客户端测试代码:

// Test.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include <afxole.h>

#include "../Ex22b/Interface.h"

 

int _tmain(int argc, _TCHAR* argv[])

{

     

    ::CoInitialize(NULL);

    CLSID clsid;

    LPCLASSFACTORY pClf;

    LPUNKNOWN pUnk;

    IMotion* pMot;

    IVisual* pVis;

 

    HRESULT hr;

    if ((hr = ::CLSIDFromProgID(L"Ex22b.Spaceship", &clsid)) != NOERROR) {

        TRACE("unable to find Program ID -- error = %x/n", hr);

        return -1;

    }

 

    if ((hr = ::CoGetClassObject(clsid, CLSCTX_INPROC_SERVER,

        NULL, IID_IClassFactory, (void **) &pClf)) != NOERROR) {

            TRACE("unable to find CLSID -- error = %x/n", hr);

            return -1;

        }

 

        pClf->CreateInstance(NULL, IID_IUnknown, (void**) &pUnk);

        pUnk->QueryInterface(IID_IMotion, (void**) &pMot); // All three

        pMot->QueryInterface(IID_IVisual, (void**) &pVis); //  pointers

        //  should work

        TRACE("main: pUnk = %p, pMot = %p, pDis = %p/n", pUnk, pMot, pVis);

 

        // Test all the interface virtual functions

        pMot->Fly();

        int nPos = pMot->GetPosition();

        TRACE("nPos = %d/n", nPos);

        pVis->Display();

 

        pClf->Release();

        pUnk->Release();

        pMot->Release();

        pVis->Release();

        AfxMessageBox("Test succeeded. See Debug window for output.");

        return 0;

}

 

 

 

原创粉丝点击