- 1、本文档共9页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
COM组件设计与应用—连接点(VC6)
COM组件设计与应用(十五)连接点(vc6.0)作者:杨老师
下载源代码一、前言 上回书介绍了回调接口,在此基础上,我们理解连接点就容易多了。二、原理图一、连接点组件原理图。左侧为客户端,右侧为服务端(组件对象) 看着好复杂呀......呵呵,其实简单的紧:(注1)1、一个 COM 组件,允许有多个连接点对象(IConnectionPoint)。?? 也就是说可以有多个发生“事件”的源头。上图就有3个连接点;2、管理这些连接点的接口叫“连接点容器”(IConnectionPointContainer)。?? 连接点容器接口特别简单,因为只有2个函数,一个是 FindConnectionPoint(),表示查找你想要的连接点;另一个是 EnumConnectionPoints(),表示列出所有的连接点,然后你去选择使用哪个。在实际的应用中,查找法使用最多,占90%,而枚举法使用只占 10%,一般在支持第三方的插件(Plug in)时才使用。(你想写个 IE 的插件吗?我们后面就要讲到啦)3、每一个连接点,可以被多个客户端的接收器(Sink)连接;?? 这个我们已经熟悉啦,还记得我们在上回书中为了管理多个回调接口,使用了 cookie 的方式进行区别吗?!三、实现组件(一)1、建立一个工作区(WorkSpace)2、在工作区中,建立一个 ATL 工程(Project)。示例程序中工程名称叫 Simple15,接受全部默认选项。3、ClassView 中,执行鼠标右键菜单命令 New Atl Object...,添加 ALT 类。4、左侧分类 Category 选择 Objects,右侧 Objects 选择 SimpleObject(其实就是默认项目)。5、名称 Name 卡片中,输入组件名称。示例程序中是 DispConnect。6、属性 Attributes 卡片中,接口类型选 Dual 双接口。注意一定要选择 Support Connection Points 来支持连接点。7、ClassView 中,选择接口(IDispConnect),鼠标右键菜单添加函数 Add Method...8、增加函数。和上回书的程序一样,增加一个接口函数计算加法,但通过连接点接口返回计算结果。9、下面该增加“事件”函数了。选择事件接口(_IDispConnectEvents),添加函数。10、该函数用来返回 Add() 函数的计算结果。11、切换到 FileView 卡片,编译IDL文件。当然你也可以直接编译全部工程。其实编译的目的是为了从IDL文件产生TLB文件,因为 VC 的 IDE 环境只有知道了 TLB 后,才能生成下面的“事件代理类的程序代码”。12、生成事件代理类程序代码。选择组件类对象(CDispConnect),执行鼠标右键菜单“实现连接点”13、选择你要让 IDE 帮你生成哪个连接点的代理程序代码。我们这个组件只有一个连接点,那只好选择它了。 (在示例二中,我们需要实现两个连接点,那个时候,你就要选择两个了)14、到此,VC 的 IDE 终于帮咱们完成了所有的框架,下面该咱们自己写真正的任务代码啦。
STDMETHODIMP CDispConnect::Add(long n1, long n2)
{
long nVal = n1 + n2;
Fire_Result( nVal ); // 调用IDE帮我们生成的代理函数代码,发出事件
return S_OK;
}
15、修正 IDE 产生的代码中的错误。你不用死记硬背错误点,只要编译一下就会报出错误了。一般 VC6 帮我们生成的代码中,有2个地方可能会有BUG。一是打开头文件,找到连接点影射宏,修改如下:
BEGIN_CONNECTION_POINT_MAP(CDispConnect)
CONNECTION_POINT_ENTRY(DIID__IDispConnectEvents) // 修改 IID_XXXX 为 DIID_XXXX
END_CONNECTION_POINT_MAP()
这个错误简直可恨,既然我们使用的是双接口连接点,它生成的代码居然不会判断吗?另一个可能的错误可能发生在代理类中的 Fire_xxxx() 函数中。在示例程序中的 Fire_Result() 函数代码,大家自己去阅读,简单说就是循环地取得每个和自己连接对象(每个cookie表示的对象)的接口指针,(如果是自动化接口,则再取得 IDispatch 接口指针),然后调用事件函数。你不理解它现在没有太大的关系,不过在后面的示例二中,它给我们产生的代码是有错误
文档评论(0)