步骤2.1:建立一个解决方案。

步骤2.2:在 该解决方案中,新建一个 vc++ 的 ATL 项目。示例程序叫 Simple2,并选择DLL方式,见图一、图二。

图一、新建 ATL 项目

图二、选择非属性化的DLL组件类型

属性化 属性化编程,是未来的方向,但我们现在先不要选它。

动态链接库(DLL) 选择它。

可执行文件(EXE) 以后再讲。

服务(EXE) 表示建立一个系统服务组件程序,系统启动后就会加载并执行的程序。

允许合并代理/存根(stub)代码 选择该项表示把“代理/存根”代码合并到组件程序中,否则需要单独编译,单独注册代理存根程序。代理/存根,这个是什么概念?还记得我们在上回书中介绍的吗?当调用者调用进程外或远程组件功能的时候,其实是代理/存根负责数据交换的。关于代理/存根的具体变成和操作,以后再说啦......

支持 MFC 除非有特殊的原因,我们写 ATL 程序,最好不要选择该项。你可能会说,如果没有MFC的支持,那CString怎么办呀?告诉你个秘密吧,一般人我都不告诉他,我后半辈子就靠着这个秘密活着了:

1、你会STL吗?可以用 STL 中的 string 代替;

2、自己写个 MyString 类,嘿嘿;

3、悄悄地、秘密地、不要告诉别人(特别是别告诉微软),把 MFC 中的 CString 源码拿过来用;

4、使用 CComBSTR 类,至少也能简化我们字符串操作;

5、直接用 API 操作字符串,反正我们大家学习 C 语言的时候,都是从这里干起的。(等于没说,呵呵)

支持 COM+ 1.0 支持事务处理的 COM+ 功能。COM+ 也许在第 99 回介绍吧。

三、添加 ATL 对象类

步骤3.1:菜单"项目\添加类..."(或者用鼠标右键在 项目中弹出菜单"添加\添加类...")并选择 ATL 简单对象。见图三。

图三、选择建立ATL简单对象

除了简单对象(只实现了 IUnknown 接口),还可以选择“ATL控件”(ActiveX,实现了10多个接口)......可以选择的组件对象类型很多,但本质上,就是让向导帮我们默认加上一些接口。在以后的文章中,陆续介绍吧。

步骤3.2:增加自定义类 CFun(接口 IFun) ,见图四。

图四、填写名称

其实,我们只需要输入简称,其它的项目会自动填写。没什么多说的,只请大家注意一下 ProgID 项,默认的 ProgID 构造方式为“项目名.简称名”。

步骤3.3:填写接口属性选项,见图 五。

图五、接口选项

线程模型 COM 中的线程,我认为是最讨厌,最复杂的部分。COM 线程和公寓的概念,留待后续介绍。现在吗......大家都选"单元"(Apartment),它代表什么那?简单地说:当在线程中调用组件函数的时候,这些调用会排队进行。因此,这种模式下,我们可以暂时不用考虑同步的问题。(注1)

接口。双重(Dual),这个非常 非常重要,非常非常常用,但我们今天不讲(注2)。切记!切记!我们的这第一个 COM 程序中,一定要选择“自定义”!!!!(如果你选错了,请删除全部内容,重新来过。)

聚合 我们写的组件,将来是否允许被别人聚合(注3)使用。“只能创建为聚合”,有点类似 C++ 中的纯虚类,你要是总工程师,只负责设计但不亲自写代码的话,才选择它。

ISupportErrorInfo 是否支持丰富信息的错误处理接口。以后就讲。

连接点 是否支持连接点接口(事件、回调)。以后就讲。

IObjectWithSite 是否支持IE的调用

四、添加接口函数

图六、调出增加接口方法的菜单

图七、增加接口函数 Add

请按照图示的方法,增加Add()函数,增加Cat()函数 。[in]表示参数方向是输入;[out]表示参数方向是输出;[out,retval]表示参数方向是输出,同时可以作为函数运算结果的返回值。一个函数中,可以有多个[in]、[out],但[retval]只能有一个,并且要和[out]组合后在最后一个位置。(注4)

图八、接口函数定义完成后的图示

我们都知道,要想改变 C++ 中的类函数,需要修改两个地方:一是头文件(.h)中类的函数声明,二是函数体(.cpp)文件的实现处。而我们现在用 ATL 写组件程序,则还要修改一个地方,就是接口定义(IDL)文件。别着急 IDL 下次就要讨论啦。

五、实现接口函数

鼠标双点图八中CFun\基项和接口\Add(...)就可以开始输入函数实现了:

1.STDMETHODIMP
CFun::Add(
long n1, long n2, long *pVal)
2.{
3.*pVal
= n1 + n2;
4. 
5.return S_OK;
6.}

这个太简单了,不再浪费“口条”。下面我们实现字符串连接的Cat()函数:

01.STDMETHODIMP
CFun::Cat(BSTR s1, BSTR s2, BSTR *pVal)
02.{
03.int nLen1
= ::SysStringLen( s1 );   
//
s1 的字符长度
04.int nLen2
= ::SysStringLen( s2 );   
//
s2 的字符长度
05. 
06.*pVal
= ::SysAllocStringLen( s1, nLen1 + nLen2 );
//
构造新的 BSTR 同时把 s1 先保存进去
07.if(
nLen2 )
08.{
09.::memcpy(
*pVal + nLen1, s2, nLen2 * 
sizeof(WCHAR)
);   
//
然后把 s2 再连接进去
10.//     
wcscat( *pVal, s2 );
11.}
12. 
13.return S_OK;
14.}

学生:上面的函数实现,完全是调用基本的 API 方式完成的。

老师:是的,说实话,的确比较烦琐。

学生:我们是用memcpy()完成连接第二个字符串功能的,那么为什么不用函数 wcscat()那?

老师:多数情况下可以,但你需要知道:由于BSTR包含有字符串长度,因此实际的BSTR字符串内容中是可以存储L''\0''的,而函数 wcscat() 是以L''\0''作为复制结束标志,因此可能会丢失数据。明白了吗?

学生:明白,明白。我看过《COM 组件设计与应用(三)之数据类型》后就明白了。那么老师,有没有简单一些的方法那?

老师:有呀,你看......

01.STDMETHODIMP
CFun::Cat(BSTR s1, BSTR s2, BSTR *pVal)
02.{
03.CComBSTR
sResult( s1 );
04.sResult.AppendBSTR(
s2 );
05. 
06.*pVal
= sResult.Copy();
07.// 
*pVal = sResult.Detach();
08. 
09.return S_OK;
10.}

学生:哈哈,好!使用了 CComBSTR,这个就简单多了。CComBSTR::Copy()和CComBSTR::Detach()有什么区别?

老师:CComBSTR::Copy() 会制造一个 BSTR 的副本,另外CComBSTR::CopyTo()也有类似功能。而CComBSTR::Detach()是使对象与内部的 BSTR 指针剥离,这个函数由于没有复制过程,因此速度稍微快一点点。但要注意,一但剥离后,就不能再使用该对象啦。

学生:老师,您讲的太牛啦,我对您的敬仰如巍巍泰山,直入云霄......

老师:STOP,STOP!留作业啦......

1、自己先按照今天讲的内容写出这个组件;

2、不管你懂不懂,一定要去观察 IDL 文件,CPP 文件;

3、编译后,看都产生了些什么文件?如果是文本的文件,就打开看看;

4、下载本文的示例程序(vc.net 2003版本)编译运行,看看效果。然后预习一下示例程序中的调用方法;

学生:知道啦,快下课吧,我要上厕所,我都憋的不行了......

老师:下课!别忘了顶我的帖子呀......

六、小结

本回介绍第一个ATL组件程序的建立步骤,而如何使用该组件,敬请关注《COM 组件设计与应用(七)》。

注1:Apartment,系统通过隐藏的窗口消息来排队组件调用,因此我们可以暂时不考虑同步问题。注意,是暂时哈。

注2:双接口表示在一个接口中,同时支持自定义接口和 IDispatch 接口。以后,以后,以后就讲。因为双接口非常重要,我们以后会天天讲、夜夜讲、常常讲------简称“三讲”:)

注3:组件的重用方法有2个,聚合和包容。

注4:这些都是 IDL 文件中的概念,以后用到什么,就介绍什么。

com学习(四)2——用 ATL 写第一个组件(vs2003)的更多相关文章

  1. com学习(四)——用 ATL 写第一个组件

    建立 ATL 工程 步骤2.1:建立一个工作区(WorkSpace). 步骤2.2:在工作区中,建立一个 ATL 工程(Project).示例程序叫 Simple1,并选择DLL方式,见图一. 图一. ...

  2. 【转载】COM 组件设计与应用(六)——用 ATL 写第一个组件

    原文:http://vckbase.com/index.php/wv/1216.html 一.前言 1.与 <COM 组件设计与应用(五)>的内容基本一致.但本回讲解的是在 vc.net ...

  3. 【转载】COM 组件设计与应用(五)——用 ATL 写第一个组件

    原文:http://vckbase.com/index.php/wv/1215.html 一.前言 1.如果你在使用 vc5.0 及以前的版本,请你升级为 vc6.0 或 vc.net 2003: 2 ...

  4. 【DM642学习笔记四】flash烧写过程——错误记录…

    (欢迎批评指正) 一,打开.cdd配置文件时出错: 解决:在FlashBurn配置窗口中,Conversion Cmd一栏可不用管:      菜单Program—Download FBTC,load ...

  5. Android学习之基础知识十二 — 第一讲:网络技术的使用

    这一节主要讲如何在手机端使用HTTP协议和服务器端进行网络交互,并对服务器返回的数据进行解析,这也是Android中最常用的网络技术. 一.WebView的用法 有时候我们可能会碰到比较特殊的需求,比 ...

  6. TCP/IP详解学习笔记 这位仁兄写得太好了.(转载)

    TCP/IP详解学习笔记   这位仁兄写得太好了   TCP/IP详解学习笔记   这位仁兄写得太好了. http://blog.csdn.net/goodboy1881/category/20444 ...

  7. (转)SpringMVC学习(四)——Spring、MyBatis和SpringMVC的整合

    http://blog.csdn.net/yerenyuan_pku/article/details/72231763 之前我整合了Spring和MyBatis这两个框架,不会的可以看我的文章MyBa ...

  8. day 83 Vue学习四之过滤器、钩子函数、路由、全家桶等

    Vue学习四之过滤器.钩子函数.路由.全家桶等   本节目录 一 vue过滤器 二 生命周期的钩子函数 三 vue的全家桶 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 Vue的过滤 ...

  9. TweenMax动画库学习(四)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

随机推荐

  1. 激活Maven profile的几种方式

    首先简单介绍下 Maven 的 profile 是什么.对于人来说,profile 是指人的肖像,轮廓,比如论坛里每个人注册了帐号后,可以设置自己的 profile,放上照片,介绍等等.对于 Mave ...

  2. Python 函数的创建和调用

    >>> movies =[ "the holy grail", 1975,"terry jones",91, ["graham ch ...

  3. ultraedit15.00.0.1046注册码

      ultraedit注册码,版本:15.00.0.1043·········· 用户名 MAYBELOVE 注册码 LFKKM-KIMMX-OSFEB-PMISO-ELILS-IIIHO-KKHLR ...

  4. ios8 ios7 tableview cell 分割线左对齐

    ios8中左对齐代码 //加入如下代码 -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cel ...

  5. Maven打包web工程成WAR

    其实不一定要通过Goals:package来打war包,直接run as maven bulid也行:

  6. SecureCRT自动记录日志【记录键入的所有命令和打印的结果信息】

  7. OpenCV实现KNN算法

    原文 OpenCV实现KNN算法 K Nearest Neighbors 这个算法首先贮藏所有的训练样本,然后通过分析(包括选举,计算加权和等方式)一个新样本周围K个最近邻以给出该样本的相应值.这种方 ...

  8. 2.Could not open Selected VM debug port (8700). Make sure you do not have another instance of DDMS or of the eclipse plugin running

    在eclipse.ini配置文件最后加上:-Djava.net.preferIPv4Stack=true 其他类似

  9. input file 上传文件

    面试的时候遇到一个问题,要求手写的方式上传文件. 本来觉得很简单,但是结果怎么也成功不了. 前台: <form ID="form1" action="AcceptF ...

  10. 转-ListView的性能优化之convertView和viewHolder

    ListView的性能优化之convertView和viewHolder 2014-05-14 参考:http://www.cnblogs.com/xiaowenji/archive/2010/12/ ...