65.9K
CodeProject 正在变化。 阅读更多。
Home

连接点实现的一种实用方法

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.77/5 (11投票s)

2006 年 9 月 22 日

CPOL

2分钟阅读

viewsIcon

51043

downloadIcon

421

本文展示了如何实际实现连接点。

引言

我已尽力使本教程非常注重实践,它展示了如何实际实现连接点,而不是专注于理论。在开始任何事情之前,我想衷心感谢 Alex C. Punnen 先生在 Code Project 上发表的文章:COM 连接点

由于这是我的第一篇文章,我衷心感谢大家的所有建议和评论。

让我们开始

创建一个带有 MFC 支持的基于控制台的应用程序。我们将其命名为 ConClient

将另一个 ATL 项目添加为当前项目的依赖项。将 ATL 项目命名为 ConServer

在我们的新 ConServer 中创建一个名为 XMath 的接口。

但这次,请选中 ConnectionPoint 复选框。

然后,构建我们的 ConServer。

您将在您的类视图中看到一个新的接口 _IXMathEvents

向我们的接口 XMath 添加一个新方法(请注意此处没有指定返回类型或 [out, retval])。

向我们的事件接口(在我们的例子中是 _IXMathEvents)添加一个新方法。

该方法应该像这样

将该方法添加到事件接口后,请右键单击我们项目的 CoClass,如下图所示

然后,如突出显示的那样,在 Implement Connection Point 对话框中,选择它。您将看到以下屏幕

如图所示,请选中标记为 _IXMathEvents 的框。之后,您将看到一些由向导为我们生成的类,名为 CProxy_IXMathEvents<class T>

同样,如果您实现连接点,您将看到一些方法,例如 Fire_ExecutionOverCProxy_IXMathEvents 类中,如果您没有在 CProxy… 类中看到 Fire_ExecutionOver 方法。

双击 CXMath->IXMath->Add 函数的 Add(int n1, int n2) 函数。并编写以下代码行

Fire_ExecutionOver(n1 + n2);

通过在 File 视图中右键单击服务器 DLL 来构建它。

如果您收到一些如下所示的错误

请将 CONNECTION_POINT_ENTRY(IID__IXMathEvents) 行更改为 CONNECTION_POINT_ENTRY(DIID__IXMathEvents)

现在将 ConClient 作为活动项目。添加一个从 CCmdTarget 派生的新类 CSink,并从 Automation 面板中选择 Automation 单选按钮。

将以下行输入到客户端的 StdAfx.h

#import "ConServer\Debug\ConServer.DLL" named_guids
using namespace CONSERVERLib;

CSink 类添加一个成员函数,如 HRESULT Add(int nResult)

打开 Sink.CPP 文件 并修改以下行。注释掉 INTERFACE_PART(CSink, IID_ISink, Dispatch) 行并添加 INTERFACE_PART(CSink, DIID__IXMathEvents, Dispatch)

BEGIN_INTERFACE_MAP(CSink, CCmdTarget)//DIID__IXMathEvents
    //INTERFACE_PART(CSink, IID_ISink, Dispatch)
    INTERFACE_PART(CSink, DIID__IXMathEvents, Dispatch)
END_INTERFACE_MAP()

在 DISPATCH MAP 中,添加以下行

DISP_FUNCTION(CSink, "Add", Add, VT_I4, VTS_I4)

更改已在 Sink.CPP 中用红线标记。

#include “Sink.h” 添加到主函数的文件中。并将以下代码行写入您的主函数

IXMathPtr ptrMath;
CoInitialize(NULL);
ptrMath.CreateInstance(__uuidof(XMath));

if(ptrMath)
{
    IConnectionPointContainerPtr ptrConPntCnt = (IDispatch*)ptrMath;
    IConnectionPointPtr ptrCon;
    IUnknown* pHandler = NULL;
    DWORD dwCookie;

    if(ptrConPntCnt != NULL)
    {
        ptrConPntCnt->FindConnectionPoint(DIID__IXMathEvents,&ptrCon);
                    
        CSink *pSink = new CSink;

        pHandler = pSink->GetInterface(&IID_IUnknown);
        ptrCon->Advise(pHandler,&dwCookie);
                
        ptrMath->Add(10, 20);

        ptrCon->Unadvise(dwCookie);

        ptrCon.Release();
        ptrConPntCnt.Release();
        delete pSink;

    }
    ptrMath.Release();
}
CoUninitialize();

成功运行此程序后,您将看到一个消息框,显示的值为 30,如下图所示

在我文章的第二个版本中,我打算使用 eVC++ 4.0 和 VS 7.0 实现连接点。

© . All rights reserved.