2013年3月22日星期五

Activex、OLE、COM、OCX、DLL之间的区别

Activex、OLE、COM、OCX、DLL之间的区别

熟悉面向对象编程和网络编程的人一定对ActiveX、OLE和COM/DCOM这些概念不会陌生,但是它们之间究竟是什么样的关系,对许多们还是比较模糊的。在具体介绍它们的关系之间,我们还是先明确组件(Component)和对象(Object)之间的区别。
组件是一个可重用的模块,它是由一组处理过程、数据封装和用户接口组成的业务对象(Rules Object)。组件看起来像对象,但不符合对象的学术定义。
它们的主要区别是:
 1)组件可以在另一个称为容器(有时也称为承载者或宿主)的应用程序中使用,也可以作为独立过程使用;
 2)组件可以由一个类构成,也可以由多个类组成,或者是一个完整的应用程序;
 3)组件为模块重用,而对象为代码重用。现在,比较流行的组件模型有COM(Component Objiect Module,对象组件模型)/DCOM( Distributed COM,分布式对象组件模型)和CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构)。
到这里,已经出现了与本文相关的主题COM,而CORBA与本文无关,就不作介绍。
之所以从组件与对象的区别说起,是想让大家明确COM和 CORBA是处在整个体系结构的最底层,如果暂时对此还不能理解,不妨继续往下看,最后在回过头看一看就自然明白了。
现在开始阐述ActiveX、OLE和COM的关系。首先,让大家有一个总体的概念,从时间的角度讲,OLE是最早出现的,然后是COM和ActiveX;从体系结构角度讲,OLE和ActiveX是建立在 COM之上的,所以COM是基础;单从名称角度讲,OLE、ActiveX是两个商标名称,而COM则是一个纯技术名词,这也是大家更多的听说ActiveX和OLE的原因。
既然OLE是最早出现的,那么就从OLE说起,自从Windows操作系统流行以来,“剪贴板”( Clipboard)首先解决了不同程序间的通信问题(由剪贴板作为数据交换中心,进行复制、粘贴的操作),但是剪贴板传递的都是“死”数据,应用程序开发者得自行编写、解析数据格式的代码,于是动态数据交换(Dynamic Data Exchange,DDE)的通信协定应运而生,它可以让应用程序之间自动获取彼此的最新数据,但是,解决彼此之间的“数据格式”转换仍然是程序员沉重的负担。
对象的链接与 嵌入(Object Linking and Embedded,OLE)的诞生把原来应用程序的数据交换提高到“对象交换”,这样程序间不但获得数据也同样获得彼此的应用程序对象,并且可以直接使用 彼此的数据内容,其实OLE是Microsoft的复合文档技术,它的最初版本只是瞄准复合文档,但在后续版本OLE2中,导入了COM。
由此可见,COM是应OLE的需求而诞生的,所以虽然COM是OLE的基础,但OLE的产生却在COM之前。 COM的基本出发点是,让某个软件通过一个通用的机构为另一个软件提供服务。COM是应OLE 的需求而诞生,但它的第一个使用者却是OLE2,所以COM与复合文档间并没有多大的关系,实际上,后来COM就作为与复合文档完全无关的技术,开始被广泛应用。
这样一来, Microsoft就开始“染指”通用平台技术。但是COM并不是产品,它需要一个商标名称。而那时Microsoft的市场专家们已经选用了OLE作为 商标名称,所以使用COM技术的都开始贴上了 OLE的标签。虽然这些技术中的绝大多数与复合文档没有关系。Microsoft的这一做法让人产生这样一个误解OLE是仅指复合文档呢?还是不单单指复 合文档?其实OLE是COM的商标名称,自然不仅仅指复合文档。但Microsoft自己恐怕无法解释清楚,这要花费相当的精力和时间。
于是,随着Internet的发展,在1996年春,Microsoft改变了主意,选择ActiveX作为新的商标名称。ActiveX是指宽松定义的、基于COM的技术集合,而OLE仍然仅指复合文档。当然, ActiveX最核心的技术还是COM。
ActiveX 和OLE的最大不同在于,OLE针对的是桌面上应用软件和文件之间的集成,而ActiveX则以提供进一步的网络应用与用户交互为主。到这里,大家应该对 ActiveX、OLE和COM三者的关系有了一个比较明确的认识,COM才是最根本的核心技术,所以下面的重点介绍COM。
让对象模型完 全独立于编程语言,这是一个非常新奇的思想。这一点从C++和Java的对象概念上,我们就能有所了解。但所谓COM对象究竟是什么呢?为了便于理解,可 以把COM看作是某种(软件)打包技术,即把它看作是软件的不同部分,按照一定的面向对象的形式,组合成可以交互的过程和以组支持库。
COM对象可 以用C++、Java和VB等任意一种语言编写,并可以用DLL或作为不同过程工作的执行文件的形式来实现。使用COM对象的浏览器,无需关心对象是用什 么语言写的,也无须关心它是以DLL还是以另外的过程来执行的。从浏览器端看,无任何区别。这样一个通用的处理技巧非常有用。例如,由用户协调运行的两个 应用,可以将它们的共同作业部分作为COM对象间的交互来实现(当然,现在的OLE复合文档也能做到)。为在浏览器中执行从Web服务器下载的代码,浏览 器可把它看作是COM对象,也就是说,COM技术也是一种打包可下载代码的标准方法(ActiveX控件就是执行这种功能的)。甚至连应用与本机OS进行 交互的方法也可以用COM来指定,例如在Windows和Windows NT中用的是新API,多数是作为COM对象来定义的。可见,COM虽然起源于复合文档,但却可有效地适用于许多软件问题,它毕竟是处在底层的基础技术。 用一句话来说,COM是独立于语言的组件体系结构,可以让组件间相互通信。
随着计算机网络的发展,COM进一步发展为分布式组件对象模型,这就是DCOM,它类似于CORBA的ORB,本文对此将不再做进一步的阐述。通过上面的讲述相信大家一定对ActiveX、OLE和COM/DCOM的关系有了一个清楚的了解。
使用 Windows的人对于ActiveX控制一定不会陌生,它提供了一种类似于DLL动态链接库的调用,不过它与DLL的唯一区别就是ActiveX不注册 不能被系统识别并使用。那么,当我们得到一个ActiveX没有被正确安装且不能使用的消息后,又要安装ActiveX怎么办呢?
1.Regsvr32程序法在Windows的System文件夹下有一个regsvr32.exe的程序,它就是Windows自己带的ActiveX注册和反注册工具。利用它也能够非常方便地注册AcitveX控件,它的用法为:regsvr32/u/s/n/i dllname, dllname其中dllname为ActiveX控件文件名,建议在安装前拷贝到System文件夹下参数有如下意义:
    /u - 反注册控件
    /s - 不管注册成功与否,均不显示提示框
   c - 控制台输出
    /i - 跳过控件的选项进行安装 (与注册不同)
    /n - 不注册控件,此选项必须与/i 选项一起使用
例如笔者要注册一amovie.ocx控件,则打入 regsvr32 amovie.ocx即可,要反注册它时只需使用 regsvr32 /u amovie.ocx就行了。
2.注册表法 所谓注册AcitveX,无非是将一些信息记录在Windows的注册表中,如Shockwave Flash Object控件,我们可以运行Regedit.exe注册表编辑程序,利用关键字进行搜索,然后把搜索得到后的注册表导出为一REG注册表文件,再将其 相应的ActiveX文件拷贝到Windows的System文件夹(一般ActiveX的文件名为OCX,安装在Windows的System文件夹 内)下,最后在要安装ActiveX的机器上双击导入刚才导出的注册表文件即可完成安装。
 
总结:Activex,OLE,COM都是微软的一些技术标准。Ole比较老后来发展成Activex,再后来发展成为COM OCX,DLL是扩展名。 Activex有两种扩展名OCX和DLL。实际上你可以把它们的扩暂名字调换。 COM作为ActiveX的更新技术,扩展名也有可能是DLL DLL文件还有可能是动态链接库。主要是装载一些函数,可以动态加载。

 

COM组件

COM组件

求助编辑百科名片

COM component(COM组件)是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术。在COM构架下,人们可以开发 出各种各样的功能专一的组件,然后将它们按照需要组合起来,构成复杂的应用系统。由此带来的好处是多方面的:可以将系统中的组件用新的替换掉,以便随时进 行系统的升级和定制;可以在多个应用系统中重复利用同一个组件;可以方便的将应用系统扩展到网络环境下;COM与语言,平台无关的特性使所有的程序员均可 充分发挥自己的才智与专长编写组件模块。

编辑本段COM方法

COM是开发软件组件的一种方法。组件实际上是一些小的二进制可执行程序,它们可以给应用程序,操作系统以及其他组件提供服务。开发自定义的COM组件就如同开发动态的,面向对象的 API。多个COM对象可以连接起来形成应用程序或组件系统。并且组件可以在运行时刻,在不被重新链接或编译应用程序的情况下被卸下或替换掉。 Microsoft的许多技术,如ActiveX, DirectX以及OLE等都是基于COM而建立起来的。并且Microsoft的开发人员也大量使用COM组件来定制他们的应用程序及操作系统。
COM所含的概念并不止是在Microsoft Windows操作系统下才有效。COM并不是一个大的API,它实际上像结构化编程及面向对象编程方法那样,也是一种编程方法。在任何一种操作系统中,开发人员均可以遵循“COM方法”。
一个应用程序通常是由单个的二进制文件组成的。当编译器生成应用程序之后,在对下一个版本重新编译并发行新生成的版本之前,应用程序一般不会发生任何变化。操作系统,硬件及客户需求的改变都必须等到整个应用程序被重新生成。
目前这种状况已经发生变化。开发人员开始将单个的应用程序分隔成单独多个独立的部分,也即组件。这种做法的好处是可 以随着技术的不断发展而用新的组件取代已有的组件。此时的应用程序可以随新组件不断取代旧的组件而渐趋完善。而且利用已有的组件,用户还可以快速的建立全 新的应用。
传统的做法是将应用程序分割成文件,模块或类,然后将它们编译并链接成一个单模应用程序。它与组件建立应用程序的过程(称为组件构架)有很大的不同。一个组件同一个微型应用程序类似,即都是已经编译链接好并可以使用的二进制代码,应用程序就是由多个这样的组件打包而得到的。单模应用程序只有一个二进制代码模块。自定义组件可以在运行时刻同其他的组件连接起来以构成某个应用程序。在需要对应用程序进行修改或改进时,只需要将构成此应用程序的组件中的某个用新的版本替换掉即可。
COM,即组件对象模型,是关于如何建立组件以及如何通过组件建立应用程序的一个规范,说明了如何可动态交替更新组件。

编辑本段组件优点

组件架构的一个优点就是应用可以随时间的流逝而发展进化。除此之外,使用组件还有一些可以使对已有应用的升级更加方便和灵活的优点,如应用的定制,组件库以及分布式组件等。
使用组件的种种优点直接来源于可以将它们动态的插入或卸出应用。为了实现这种功能,所有的组件必须满足两个条件:第一,组件必须动态链接;第二,它们必须隐藏(或封装)其内部实现细节。动态链接对于组件而言是一个至关重要的要求,而消息隐藏则是动态链接的一个必要条件。
COM组件由以Win 32动态连接库(DLL)或可执行文件(EXE)形式发布的可执行代码所组成。遵循COM规范编写出来的组件将能够满足对组件架构的所有要求。COM组件可以给应用程序、操作系统以及其他组件提供服务;自定义的COM组件可以在运行时刻同其他组件连接起来构成某个应用程序;COM组件可以动态的插入或卸出应用。
恶意网站可以利用含有漏洞的com组件接口,下载木马,并且执行;
禁用com组件一般是指设置了Kill位,即IE浏览器不能使用这个组件,通俗讲:通过设置Kill位,可以使 InternetExplorer在使用默认设置时永不调用被禁用的com组件,从而禁止该控件在Internet Explorer中运行。禁用含有漏洞的com组件后,IE就不能调用含有漏洞的COM组件;黑客利用有漏洞的COM组,写成的网页代码就不能在IE中被执行,木马等将不会被下载。

编辑本段相关问题

禁用com组件可能导致的问题

在线播放功能的组件被禁用,会导致在线电影等在线视频无法正常观看;
在线杀毒功能的组件被禁用,会导致在线杀毒不能使用;
在线游戏功能的组件被禁用,会导致在线游戏无法玩,
com组件禁用后的具体情况,需要根据具体的com组件功能作判断。

手动启动COM组件操作方法:

运行——regedit——找到被禁用的com组件对应的clsid|注册表键值——删除具体值,或者整个键。
COM是Component Object Model (组件对象模型)的缩写。 用户需要什么样的软件产品?这是一个多选题,但高效,健壮是肯定会被选中的。作为一名软件开发人员如何做才能满足用户的需要呢?必须要保证升级应用时不破坏与以前版本的向后兼容性。必须做到扩展系统服务时不依赖特定的操作系统。面向对象的程序设计显然是一次革命性的改变。采用面向对象的设计方法我们可以很容易的把要解决的问题事物抽象成各种类,并将内部动作封装隐藏起来,只提供一些接口。但这并没有完全解决我们的问题。昨天我在《程序员》杂志上看到,现在是后OO时代,那OO以后是什么呢?应该是面向组件吧。
手动启动COM组件操作方法:
运行——regedit——找到被禁用的com组件对应的clsid|注册表键值——删除具体值,或者整个键。
刚刚读完《COM技术内幕》一书,整理了一个FAQ,供大家在学习此书时参考。
这是第一部分,包含前3章的内容。
FAQ1:什么是COM组件?〖第一章〗
Answer:
COM组件是以WIN32动态链接库(DLL)或可执行文件(EXE)形式发布的可执行代码组成。
COM组件是遵循COM规范编写的
COM组件是一些小的二进制可执行文件
COM组件可以给应用程序、操作系统以及其他组件提供服务
自定义的COM组件可以在运行时刻同其他组件连接起来构成某个应用程序
COM组件可以动态的插入或卸出应用
COM组件必须是动态链接的
COM组件必须隐藏(封装)其内部实现细节
COM组件必须将其实现的语言隐藏
COM组件必须以二进制的形式发布
COM组件必须可以在不妨碍已有用户的情况下被升级
COM组件可以透明的在网络上被重新分配位置
COM组件按照一种标准的方式来宣布它们的存在
FAQ2:组件不是……?〖第一章〗
Answer:
COM组件不是一种计算机语言
COM组件不是DLL,只是利用DLL来给组件提供动态链接的能力
COM组件不是一个API函数集。
COM组件不是类
FAQ3:什么是接口?〖第二章〗
Answer:
接口就是提供两个不同对象间的一种连接。
计算机程序是通过一组函数而进行连接的,这组函数就是定义了程序中不同部分的接口。
DLL的接口就是它所输出的那些函数。
C++类的接口就是该类的成员函数集。
COM中的接口是一组由组件实现的提供给客户使用的函数。
在COM中接口是一个包含函数指针数组的内存结构,数组元素是一个由组件实现的函数地址。
FAQ4:接口的作用是什么?〖第二章〗
Answer:
有了组件如何将它们连接起来构成某个应用程序,需要用接口。
在COM中接口就是一切,对客户说组件就是接口集,客户只能通过接口和组件打交道。
说明接口可以保护系统免受外界变化的影响。这是封装的体现。
接口实现了使用户使用同样的方式来处理不同的组件。这是多态的体现。
FAQ5:什么是IUnKnown? 〖第三章〗
Answer:
IUnKnown是一个接口。
所有COM接口都继承IUnKnown。
IUnKnown的定义在WIN32 SDK中的UNKNWN头文件中。
///IUnKnown的定义
interface IUnKnown
{
virtual HRESULT __stdcall QueryInterface(const IID& iid,void **ppv)=0;
virtual ULONG __stdcall AddRef()=0;
virtual ULONG __stdcall Release()=0;
}
FAQ6:QueryInterface函数的作用是什么?〖第三章〗
Answer:
QueryInterface是IUnKnown的成员函数,客户可以通过此函数来查询组件是否支持某个特定的接口。
QueryInterface函数返回一个指向组件支持的接口的指针
如果QueryInterface函数没有找到组件支持的接口则返回指针是NULL。
QueryInterface函数可以使用if…then…else语句、数组、散列表、树来实现。
QueryInterface函数不能使用case语句,因为QueryInterface函数返回的是一个HRESULT结构而不是一个数。
QueryInterface也是一种无封处理组件版本的机制。这种机制使得组件的新旧不同的版本可以互操作。
FAQ7:QueryInterface函数的实现规则是什么?〖第三章〗
Answer:
QueryInterface返回的IUnKnown指针总是相同。
若客户获得了某个接口,那么它总能获得此接口。
客户可以再次获得已经拥有的接口。
客户可以返回到起始接口。
若能够在某个接口获得某个特定接口,那么从任意接口都将可以获得此接口。
FAQ8:接口的如何实现?
Answer:
COM接口在C++中是用纯抽象基类实现。
一个COM组件可以支多个接口。
一个C++类可以使用多重继承来实现一个支持多个接口的组件。
组件可以支持任意数目的接口。
接口应该具有不变性。在组件升级时应该不修改原来的接口,而是添加新的接口。
要精心设计实现接口,以使之能够支持各种不同的实现。
FAQ9:QueryInterface函数的参数IID是什么?〖第三章〗
Answer:
它是一个结构,接口标识符结构。
IID标识了客户所需的接口。
每一个接口都有一个唯一的接口标识符。所以某个与IID相对应的接口绝对不会发生变化。
接口IID决定了COM组件的版本。
不同的接口具有不同的ID,包括不同版本的接口。
FAQ10:何时需要建立一个新的COM组件版本?〖第三章〗
Answer:
当为已有接口指定新的ID时应该是下面的条件至少有一个成立。
接口中函数的数目发生改变时。
接口中函数的顺序发生改变。
接口中某个函数的参数发生改变
接口中某个函数的参数的顺序发生改变
接口中某个函数的参数的类型发生改变
接口中函数的返回值发生改变
接口中函数的返回值类型发生改变
接口中函数的参数的含义发生改变
接口中函数的含义发生改变
简单地说,COM是一种跨应用和语言共享二进制代码的方法。与C++不同,它提倡源代码重用。ATL便是一个很好的例证。源码级重用虽然好,但只能用于C++。它还带来了名字冲突的可能性,更不用说不断拷贝重用代码而导致工程膨胀和臃肿。
Windows使用DLLs在二进制级共享代码。这也是Windows程序运行的关键——重用kernel32.dll, user32.dll等。但DLLs是针对C接口而写的,它们只能被C或理解C调用规范的语言使用。由编程语言来负责实现共享代码,而不是由DLLs本身。这样的话DLLs的使用受到限制。
MFC引入了另外一种MFC扩展DLLs二进制共享机制。但它的使用仍受限制——只能在MFC程序中使用。
COM通过定义二进制标准解决了这些问题,即COM明确指出二进制模块(DLLs和EXEs)必须被编译成与指定的结构匹配。这个标准也确切规定了在内存中如何组织COM对象。COM定义的二进制标准还必须独立于任何编程语言(如C++中的命名修饰)。一旦满足了这些条件,就可以轻松地从任何编程语言中存取这些模块。由编译器负责所产生的二进制代码与标准兼容。这样使后来的人就能更容易地使用这些二进制代码
在内存中,COM对象的这种标准形式在C++虚函数中偶尔用到,所以这就是为什么许多COM代码使用C++的原因。但是记住,编写模块所用的语言是无关的,因为结果二进制代码为所有语言可用。
此外,COM不是Win32特有的。从理论上讲,它可以被移植到Unix或其它操作系统。但是我好像还从来没有在Windows以外的地方听说过COM。
当然COM对象也需要用过一种特殊的逻辑来从内存中释放对象。这种方法被称为COM对象的引用计数。它是用来跟踪活 动引用的数目。当一个对象的引用计数为0,对象从内存中删除。出现这种情况的主要问题是循环引用。如果存在两个COM组件之间的循环引用,他们会不会从内 存中释放。

[转]使用C#开发ActiveX控件全攻略

[转]使用C#开发ActiveX控件全攻略

转自:http://lwchome.spaces.live.com/blog/cns!791B533443007D37!234.entry
 
前言:
这段时间因为工作的需要,研究了一下ActiveX控件。总结如下:
先说说ActiveX的基本概念。
根据微软权威的软件开发指南MSDN(Microsoft Developer Network)的定义,ActiveX插件以前也叫做OLE控件或OCX控件,它是一些软件组件或对象,可以将其插入到WEB网页或其它应用程序中。
    ActiveX是Microsoft对于一系列策略性面向对象程序技术和工具的称呼,其中主要的技术是组件对象模型(COM)。在有目录和其它支持的网络 中,COM变成了分布式COM(DCOM)。在创建包括ActiveX程序时,主要的工作就是组件,一个可以自足的在ActiveX网络(现在的网络主要 包括Windows和Mac)中任意运行的程序。这个组件就是ActiveX近控件。ActiveX是Microsoft为抗衡Sun Microsystems的JAVA技术而提出的,此控件的功能和JAVA applet功能类似。
目前支持ActiveX的主要是IE浏览器。
以 前ActiveX开发普遍使用VC++或VB,随着C#和.net的发布,用C#开发ActiveX控件变得更方便、更简单。但需要注意的是用C#开发 的ActiveX控件需要客户机装有.net framework,有点郁闷。可是相对.net强大的功能良好的易用性,这点牺牲还是值得的,况且现在好多计算机已经安装有.net framework了。
其实.net下的winform控件也是可以直接嵌入到web网页里的,但是由于.net安全性的限制,无法在客 户端实现复杂的操作,比如磁盘空间操作和注册表操作。因为ActiveX控件是以本地用户的身份运行,可以突破.net安全性的限制,所以开发 ActiveX控件还是很必要的。
    C#写ActiveX控件的原理很简单,就是使用了.net平台和COM的互操作性。修改项目属性的目的就是将.net控件注册为com。这样,你就可以 把这个控件完全当作ActiveX控件来对待了。比如,可以使用JS和VBS来调用,也可以使用C++来调用。
下面一步步来实现C#写ActiveX控件。
第一部分:用vs2008制作一个winForm控件
用vs2008建立一个新的“windows窗体控件库”命名为“WindowsFormsControlLibrary1”如下图
clip_image001
点击确定后,将UserControl1.cs更名为demo.cs。向界面里添加一个Labal、一个TextBox和一个Button,相应的修改控件属性。如下图:
clip_image002
为button1添加Click事件,代码如下:
private void button1_Click(object sender, EventArgs e)
        {
            label1.Text = textBox1.Text;
        }
在AssemblyInfo.cs中引用System.Security命名空间,并添加一句:
clip_image003
[assembly : AllowPartiallyTrustedCallers()]
好,现在编译整个工程,生成\bin\Debug\WindowsFormsControlLibrary1.dll,我们的winform控件就做好了。
下面在解决方案里添加一个web应用程序的工程,名为WebApplication1,用来测试我们的控件。
将WindowsFormsControlLibrary1.dll拷贝到WebApplication1所在的目录下。然后在Default.aspx 里面加入“<object id="helloworld" classid='http://localhost:59639/WindowsFormsControlLibrary1.dll#WindowsFormsControlLibrary1.demo' width="184" height="96" >
    </object>
    ok,编译运行后你将看到如下界面:
clip_image004
第二部分:把这个winForm控件转换为ActiveX控件
到目前为止,我们所实现的只是winform控件,还不是真正的ActiveX控件。
鼠标右键,打开WindowsFormsControlLibrary1的工程属性,在“应用程序”里点击“程序集信息...”显示如下界面:
clip_image005
选中“使程序集COM可见”,然后确定。
进入“生成”页面,如下图:
clip_image006
选中“为COM互操作注册”。
重新编译工程,这时WindowsFormsControlLibrary1.dll就变成了一个ActiveX控件。
我们使用 工具—〉OLE/COM对象查看器查看,如图:
clip_image007
    WindowsFormsControlLibrary1.demo已经被正确识别为COM组件。现在,我们已经可以像使用其它ActiveX控件一样在 网页中显示了。在WindowsFormsControlLibrary1.demo点击鼠标右键,选择Copy HTML <object> Tag to Clipboard,可以将代码拷入剪贴板。
我们在 Default.aspx  中粘贴剪贴板的内容,如下:
     <object id="helloworld" classid="clsid:A82F92E1-BA7F-3B32-B389-584E8AB4441F" width="184"> 
        </object>
编译运行整个工程,我们会在网页中看到之前的内容。好,现在我们的控件已经是货真价实的ActiveX控件了。
第三部分:实现ActiveX控件与网页的交互
我们在Demo中加入s1属性:
        private string _s1;
        public string s1
        {
            get
            {
                return _s1;
            }
            set
            {
                _s1 = value;
            }
        }
我们在Demo中加入ShowMessage方法:
    public void showMessage()
        {
            MessageBox.Show(_s1);
        }
修改Default.aspx  中的内容:
        <object id="helloworld" classid="clsid:A82F92E1-BA7F-3B32-B389-584E8AB4441F"
            width="184">
            <param  name="s1" value="用param传递控件属性"/>  
        </object>
        <input type='button' onclick='helloworld.ShowMessage()' value='用param传递控件属性'/>
        <input type='button' onclick='helloworld.s1="用js和控件交互"; helloworld.ShowMessage()' value='用js和控件交互'/>
好,编译运行整个工程,显示如下:
clip_image008
点击单击“用js和控件交互”按钮,应该可以实现交互了。
但是结果却很遗憾,我们发现IE跳出了对话框,如图所示
clip_image009
这时我们通过修改IE安全属性“对没有标记为安全的ActiveX控件进行初始化和运行”可以绕过这个问题,但是要真正解决需要实现IObjectSafety接口,把ActiveX控件标记为安全的ActiveX控件。
首先在工程里添加一个接口,命名为IObjectSafety.cs,代码如下:
using System;
using System.Runtime.InteropServices;
namespace WindowsFormsControlLibrary1
{
    [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        void GetInterfacceSafyOptions( System.Int32 riid,out System.Int32 pdwSupportedOptions, out System.Int32 pdwEnabledOptions);
        void SetInterfaceSafetyOptions( System.Int32 riid, System.Int32 dwOptionsSetMask, System.Int32 dwEnabledOptions); 
    }
}
注意添加命名空间“using System.Runtime.InteropServices”,Guid一定不能搞错。
然后在demo类里添加继承,如下:
public partial class demo : UserControl, WindowsFormsControlLibrary1.IObjectSafety
{...}
最后在demo类里实现两个特定方法:
public void GetInterfacceSafyOptions(Int32 riid, out Int32 pdwSupportedOptions, out Int32 pdwEnabledOptions)
{
// TODO: 添加 WebCamControl.GetInterfacceSafyOptions 实现 
pdwSupportedOptions = 1;
pdwEnabledOptions = 2;
}
public void SetInterfaceSafetyOptions(Int32 riid, Int32 dwOptionsSetMask, Int32 dwEnabledOptions)
{
// TODO: 添加 WebCamControl.SetInterfaceSafetyOptions 实现             
}
    重新编译,然后将IE里面的设置改回来。现在,我们发现,和JS的交互已经没有问题了。
在前面我们已经完成了ActiveX控件的开发,接下来的就是发布它了。
第四部分:制作安装包
在解决方案了添加一个“安装”项目,命名为SetupActiveX。
在项目的“应用程序文件夹”里添加“主输出项目”WindowsFormsControlLibrary1
将主输出项目”WindowsFormsControlLibrary1的Register属性改为vsdrpCOM.如图:
clip_image010
现在我们生成安装程序,并把相应得程序拷贝到正确的目录中(本例中为默认网站目录下的跟文件夹中)。
现在我们又要重新改动Default.aspx  文件了。修改后的结果如下: 
    <div>
        <object id="helloworld" classid="clsid:A82F92E1-BA7F-3B32-B389-584E8AB4441F"
            width="184"
            codebase="Setup.exe">
            <param  name="s1" value="用param传递控件属性"/>  
        </object>
        <input type='button' onclick='helloworld.ShowMessage()' value='用param传递控件属性'/>
        <input type='button' onclick='helloworld.s1="用js和控件交互"; helloworld.ShowMessage()' value='用js和控件交互'/>
    </div>
注意,我们在object块中加入了codebase属性,这就是制定的下载控件的位置,可以使用相对路径。
但是,我们现在还不能正确请求这个页面,因为我们还没有对我们的控件进行签名。为了绕过这个问题,我们可以修改IE的安全属性"对没有标记为安全的ActiveX控件进行初始化和脚本运行"和"下载未签名的ActiveX控件"。
第五部分:给安装包签名
对于 Internet 应用程序的开发人员和用户而言,代码安全是一个主要问题。有下列风险:恶意的代码、被篡改的代码和来自未知站点或作者的代码。
     Internet 开发时有两种保证安全的基本方法。第一种方法称为“沙箱”。在此方法中,应用程序只能访问一组特定的API,并且被从潜在危险的 API(如文件 I/O,程序可能在此毁坏用户计算机中的数据)中排除。第二种方法使用数字签名来实现。此方法对 Internet 称为“收缩包装”。使用私匙/公匙技术验证和签名代码。在代码运行之前,验证其数字签名,确保该代码的来源是已知的并且经过验证,并且自签名后该代码未被 更改过。
在第一种情形中,信任应用程序不会有任何损害,并且信任该应用程序的来源。在第二种情形中,使用数字签名来验证真伪。数字签名 是用于识别和提供关于代码发行者的详细资料的工业标准。其技术基于标准,包括 RSA 和 X.509。浏览器一般允许用户选择是否希望下载并运行来源未知的代码。
给文件签名首先要获得软件发行证书。为此,必须向证书颁发机构 提出请求(比如微软或其他认证代理机构)。在申请期间,必须生成一个密匙对并向证书颁发机构提供标识信息(如名字、地址和公匙)。还必须作出在法律上具有 约束力的保证,即保证您不能也不会分发您知道或本应知道含有病毒或将以其他方式恶意损害用户的计算机或代码的软件。当然,这种认证是收费的,一般在2—— 8KRMB不等。
这里,我们使用Microsoft.Net带的MAKECERT和CERT2SPC实用工具生成测试的软件发行证书。然 后用这个测试证书通过 SignTool工具为我们的发行包签名,当然,这对软件发行是无效的,也就是说在Internet环境下还是需要修改IE安全设置才可以下载安装。但是 在局域网环境下可以实现直接下载安装,仅可用于测试代码签名。
     MAKECERT.exe、CERT2SPC.exe和SignTool.exe三个工具在C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin 目录下。你可以通过vs2008的“Visual Studio 2008 Command Prompt” 进入命令行状态,这时系统会自动加载对应的Path参数,你在任何一个目录下都可以直接运行着三个小工具了。
    1、用MAKECERT.exe创建用于数字签名的公钥和私钥对
在命令行下输入“makecert -ss lwchome -n "CN=lwchome CRD公司" -sv d:\test\lwchomecert.pvk -r d:\test\wchomecert.cer”
其 中ss-主题的证书存储名称, n-证书颁发对象,此名称必须符合 X.500 标准。最简单的方法是在双引号中指定此名称,并加上前缀 CN=;例如,"CN=myName"。注意这里的CN必须大写。-r-证书存储位置,-sv 导出私钥文件(为了签名使用)。注意:这个时候会让输入三次密码,三次要完全一致。
2、用Cert2Spc.exe生成spc发行者证书:cert2spc d:\test\lwchomecert.cer d:\test\lwchomecert.spc
    3、用SignTool.exe对安装包数字签名
       在命令行下输入“signtool signwizard”,会弹出签名工具界面如下:
clip_image011
点击下一步,输入安装包的位置:
clip_image012
点击下一步,选择“自定义”
clip_image013
点击下一步,从文件选择:
clip_image014
选择刚刚制作的证书d:\test\lwchomecert.spc,点击下一步:
clip_image015
选择磁盘上的私密钥文件,选中刚刚生成的私密钥d:\test\lwchomecert.pvk ,然后点击下一步,输入刚刚的密码显示如下界面:
clip_image016
选择md5,点击下一步:
clip_image017
此页无需修改,直接点击下一步:
clip_image018
输入描述和web位置,点击下一步:
clip_image019
添加时间戳http://timestamp.verisign.com/scripts/timstamp.dll,点击下一步:
clip_image020
完成输入刚刚的密码即可。
这时,鼠标右击安装包文件“setup.exe”,可以查看数字签名信息:
clip_image021
如果是正式发行,请从微软或代理机构申请正式证书和密钥,然后用signtool工具加密你的发行包即可。
第六部分:部署
将签名的setup.exe拷贝到网站目录下,替换之前没有签名的安装包。用iis发布网站,注意“执行权限选择纯脚本”
qishichang

COM组件开发实践(一)


 Preface
      因为项目需要,开始从事ActiveX方面的工作,看了一些资料,可惜都是些COM原理方面的,没有切合实际动手的东西,在CodeProject上读完David Marcionek的文章【1】后,收获良多,但也遇到一些恼人的小问题,因此在其基础上就一些易错点做些小注解。本文版权归David Marcionek所有。
简介
本文目的在于让你快速掌握ActiveX控件开发技术,将会展示开发ActiveX应该知道的基本概念,如方法,属性和事件,以及如何在一个ActiveX控件和一个web页面之间进行通信
在本文中,我们将创建一个ActiveX控件,当加载控件时,它会显示一个动画进度条,以便向用户表明控件正在加载。此控件会包含展示如何在控件和web页面间传递信息的功能。下面我们会使用VS2005一步步进行开发的。
创建一个ActiveX控件
为了创建一个ActiveX控件,如下所示:
1,创建一个"MFC ActiveX Control"项目,取名MyActiveX,
2,在"MFC ActiveX Control Wizard"对话框中,选中"Control Settings"
3,"Create control based on"中选择"STATIC".我们将使用静态控件,因为我们只是显示从控件中获取的输出信息,并不接受输入信息。
4,在"Additional features"中,确保"Activates when visible""Flicker-free activation"被选中,"Has an About box dialog"不选中。
5,默认情况下,wizard会创建一个项目,使其在一个共享DLL中使用MFC.我们必须更改这种情况,因为除非所需的MFC DLL都已经在系统中安装了,否则ActiveX控件就不能运行。包含ActiveX控件的Web页面上出现红叉的一个原因就是此。在项目的属性中,"Configuration Properties"-->"General",“Use of MFC” 改为“Use MFC in a Static Library”.
6,向导会创建如下几个类:
      1)CMyActiveXApp:这是ActiveX应用程序类,从COleControlModule类继承下来的。它是OLE控件模块对象继承自的基类,包含了初始化(InitInstance)和清理(ExitInstance)的代码
      2)CMyActiveXCtrl:COleControl继承而来,这里是我们实现控件大部分功能的地方。
      3)CMyActiveXPropPage:COlePropertyPage继承而来,用于管理控件的属性页对话框。向导已经为我们创建了一个默认的对话框来作为控件的属性页对话框。

增加动画GIF支持
      这里我们使用了一个CPictureEx类(具体代码见最后的资源部分),vs2005增加一个动画GIF资源有一个bug(其实在vs2008中也存在),我们可以使用下面这种技巧来回避它:
ProcessingProgressBar.gif拷贝到项目文件夹下,然后更名为ProcessingProgressBar.gaf在资源视图中,右键资源文件MyActiveX.rc,选择添加资源。在添加资源对话框中,按下导入按钮,并选择ProcessingProgressBar.gaf文件。在自定义资源类型对话框中输入“GIF”作为资源类型。这就会将GIF图片文件导入项目中。然后将导入的图片IDIDR_GIF1 改为IDR_PROGRESSBAR.
现在开始着手恢复原状,首先,打开MyActiveX.rc的源文件,找到IDR_PROGRESSBAR的定义,将其文件名改为 ProcessingProgressBar.gif”.同样地,把项目文件夹下的图片文件名也改回为“ProcessingProgressBar.gif”,最后在解决方案资源管理器视图中,选中ProcessingProgressBar.gaf,在其属性中,修改相对路径 ."ProcessingProgressBar.gif”.
增加对话框
      现在,我们为进度条图像增加一个对话框。
1, 资源视图中,右键对话框,选择插入对话框来创建一个默认的对话框。
2, 删除默认产生的确定取消按钮,调整对话框大小为230*40
3,更改对话框IDIDD_MAINDIALOG,并修改对话框属性:Border—none, Style – Child, System Menu – False, Visible – True.
4,在对话框中加入一个图片控件,调整其大小为200*20,更改控件IDIDC_PROGRESSBAR,颜色为“white”
5,为对话框创建一个类,名为CMainDialog,
 现在我们为类增加成员变量:
1,CMyActiveXCtrl类增加一个变量m_MainDialog,类型为CMainDialog
2, CMainDialog类增加一个变量m_ProgressBar,类型为CPictureEx,这里注意确保控件变量选中,并且对于的控件是”IDC_PROGRESSBAR”.
增加支持代码
好了,现在加入一些代码来绘制主对话框和进度条控件吧。
1,为CMyActiveXCtrl处理WM_CREATE事件的代码,在其中加入:
m_MainDialog.Create(IDD_MAINDIALOG, this);
并在OnDraw函数中加入:
m_MainDialog.MoveWindow(rcBounds, TRUE);
CBrush brBackGnd(TranslateColor(AmbientBackColor()));
pdc
->FillRect(rcBounds, &brBackGnd);
     2.CMainDialog类中,加入处理WM_CREATE事件的代码,在其中加入:
if(m_ProgressBar.Load(MAKEINTRESOURCE(IDR_PROGRESSBAR),_T("GIF")))
m_ProgressBar.Draw();
Ok,一个简单的ActiveX控件已经开发完毕,设置编译模式为“Release”模式,并构建整个应用程序。
创建一个Web页面作为ActiveX控件容器
      可以使用微软的ActiveX Control Pad。要利用它在Web页面中插入一个ActiveX控件,在<BODY>标记中右键,选择“Insert ActiveX Control”,选择你需要的就可以了。


 直接打开Web页面或者放到IIS服务器上进行访问,一切顺利的话就可以看到下面的图像:

注1:前面要求设置编译模式为“Release”,其实是为了避免运行时因为触及Assert出错而做的,否则会报错如下:

 跟踪调试后会发现:

  可以看出是图片扩展控件加载时的顺序有些问题,但在浏览器中并不需要考虑如此多,因此这里忽略此Assert条件。
 2:作者在这里没有对MyActiveX.idl文件进行讲解,我认为是一个不小的失误,也正是因为如此,才会导致一个很容易犯错的地方,当我们按照他的教程,仿照他的代码一步步进行完后,却发现在ActiveX测试容器中是可以运行通过的,但到了浏览器中却死活都是红叉叉。。。,就是因为作者忽略了其对MyActiveX.idl接口定义文件的修改进行解释。
注3:VS2008中没有ActiveX控件测试容器了,VS05以上的数字签名工具也改变了,因此使用VS2005可能更好
     我按照教程一步步模仿着做的时候,在上面这两点上纠缠了3个多小时才发现问题的原因。
     在下一篇文章中,将介绍如何对ActiveX控件进行数字签名并使其自注册和销毁来确保其安全性,此外还会介绍如何在ActiveX控件和Web页面间进行数据通信。

VC++、MFC、COM和ATL的区别

VC++、MFC、COM和ATL的区别

一、什么是MFC
    微软基础类(Microsoft Foundation Classes),实际上是微软提供的,用于在C++环境下编写应用程序的一个框架和引擎,VC++是WinOS下开发人员使用的专业C++ SDK(SDK,Standard SoftWare Develop Kit,专业软件开发平台),MFC就是挂在它之上的一个输助软件开发包,MFC作为与VC++血肉相连的部分(注意C++和VC++的区别:C++是一 种程序设计语言,是一种大家都承认的软件编制的通用规范,而VC++只是一个编译器,或者说是一种编译器+源程序编辑器的 IDE,WS,PlatForm, MFC同 BC++集成的VCL一样是一个非外挂式的软件包,类库,只不过MFC类是微软为VC++专配的)。MFC是Win API与C++的结合。
最 后要明白MFC不只是一个功能单纯的界面开发系统,它提供的类绝大部分用来进行界面开发,关联一个窗口的动作,但它提供的类中有好多类不与一个窗口关联, 即类的作用不是一个界面类,不实现对一个窗口对象的控制(如创建,销毁),而是一些在WinOS(用MFC编写的程序绝大部分都在WinOS中运行)中实 现内部处理的类,如数据库的管理类等。
二、什么是COM
    所谓COM(Componet Object Model,组件对象模型),是一种说明如何建立可动态互变组件的规范,此规范提供了为保证能够互操作,客户和组件应遵循的一些二进制和网络标准。通过这 种标准将可以在任意两个组件之间进行通信而不用考虑其所处的操作环境是否相同、使用的开发语言是否一致以及是否运行于同一台计算机。
COM 的优点,首先:用户一般希望能够定制所用的应用程序,而组件技术从本质上讲就是可被定制的,因而用户可以用更能满足他们需要的某个组件来替换原来的那个。 其次,由于组件是相对应用程序独立的部件,我们可以在不同的程序中使用同一个组件而不会产生任何问题,软件的可重用性将大大的得到增强。第三,随着网络带 宽及其重要性的提高,分布式网络应用程序毫无疑问的成为软件市场上越来越重要的买点。组件价构可以使得开发这类应用程序的过程得以简化。
三、什么是ATL
ATL是ActiveX Template Library的缩写,它是一套C++模板库。使用ATL能够快速地开发出高效、简洁的代码,同时对COM组件的开发提供最大限度的代码自动生成以及可视化支持。
在ATL产生以前,开发COM组件的方法主要有两种:一是使用COMSDK直接开发COM组件,另一种方式是通过MFC提供的COM支持来实现。
直 接使用COMSDK开发COM组件是最基本也是最灵活的方式。通过使用Microsoft提供的开发包,我们可以直接编写COM程序。但是,这种开发方式 的难度和工作量都很大,一方面,要求开发者对于COM的技术原理具有比较深入的了解;另一方面,直接使用COMSDK要求开发人员自己去实现COM应用的 每一个细节,完成大量的重复性工作。这样做的结果是,不仅降低了工作效率,同时也使开发人员不得不把许多精力投入到与应用需求本身无关的技术细节中。虽然 这种开发方式对于某些特殊的应用很有必要,但这种编程方式并不符合组件化程序设计方法所倡导的可重用性,因此,直接采用COMSDK不是一种理想的开发方 式。
使用MFC提供的COM支持开发COM应用可以说在使用COMSDK基础上提高了自动化程度,缩短了开发时间。MFC采用面向对象的方 式将 COM的基本功能封装在若干MFC的C++类中,开发者通过继承这些类得到COM支持功能。为了使派生类方便地获得COM对象的各种特性,MFC中有许多 预定义宏,这些宏的功能主要是实现COM接口的定义和对象的注册等通常在COM对象中要用到的功能。开发者可以使用这些宏来定制COM对象的特性。
四、总结
对 于程序员来说,还有一个区别就是ATL要求你懂得更多的COM知识,这样你才能直接使用ATL来编写COM组件或者控件,而MFC甚至不要求你知道COM 是个什么东西就能写出一个ActiveX控件来了。此外,如果你编写的控件有GUI(图形用户界面)的话,你最好使用MFC;如果根本不需要GUI,那最 好使用ATL编写,当然你也可以选择MFC来编写不可见的控件,但是开销比ATL大,而执行效率却小于ATL;但是有时候这种差别所带来影响可以忽略掉的 话,那么我建议你还是用MFC来写,唯一的理由是它开发起来更简单,易于调试。

com与activex

一、ActiveX的由来 ActiveX最初只不过是一个商标名称而已,它所涵盖的技术并不是各自孤立的,其中多数都与Internet和Web有一定的关联。更重要的 是,ActiveX的整体技术是由Microsoft的COM(Component Object Model,组件对象模型)构筑的。但不要误认为ActiveX是定义了所有包含基于COM的技术。COM与Microsoft Office和Windows以及Microsoft现在所做的一切都有关联,但显然这些产品并不是ActiveX家族中的成员。

ActiveX 是从Microsoft的复合文档技术——OLE成长起来的。OLE最初发布的版本,只是瞄准复合文档,但在后续版本OLE2中,导入了 COM。COM是应OLE设计者的需求而诞生的。其基本的出发点是想让某个软件通过一个通用的机构为另一个软件提供服务。因而,COM的第一个使用者是 OLE2。实际上,COM与复合文档间,没有多大关系。后来,COM就作为与复合文档完全无关的技术,开始被广泛使用。这样一来,Microsoft就开 始"染指"通用平台技术。但COM不是产品,它需要一个商标名称。不巧,市场专家们选用了"OLE"作为商标名称。于是,使用COM的技术都开始贴上了 OLE的标签。当然,这些技术中的绝大部分与复合文档没有关系。Microsoft要想向人们解释:"OLE不单单是指复合文档!",这要花费相当的精力 和时间。

于是,在1996年春,Microsoft改变了主意,选择了ActiveX作为新商标名。ActiveX是指宽松定义的、基于COM的技术集合,而OLE仍然仅指复合文档。当然,最重要的核心还是COM。

让 对象模型完全独立于编程语言,这是一个非常新奇的思想。从C++和Java的对象上,我们就能有所了解。但所谓COM对象究竟是什么?为了便于理解,可以 把COM看作是某种(软件)打包技术,即把它看作是使软件的不同部分,按照一定的面向对象的形式,组合成可以交互的过程和一组支持库。COM对象可以用 C++、Java和VB等任意一种语言编写,并可以DLL或作为不同过程工作的执行文件的形式来实现。使用COM对象的客户端,无需关心对象是用什么语言 写的,也无需关心它是以DLL、还是以另外的过程来执行的。从客户端来看,无任何区别。

这样一个通用的处理技巧非常有用。例如,由用户协 调运行的两个应用,可以将它们的共同作业部分,作为COM对象间的交互来实现(当然,现在的OLE复合文档也能做到)。为在浏览器中执行而从Web服务器 下载的代码,浏览器可把它看作是COM对象。即是说,COM技术也是一种打包可下载代码的标准方法 (ActiveX控件执行这种功能)。

甚至连应用与本机OS进行交互的方法,也可以用COM来指定(Windows和Windows NT用的新API,多数是作为COM对象来定义的)。COM虽然起源于复合文档,但却可有效地适用于许多软件问题。
二、ActiveX王国 Active平台是Microsoft的世界观。其基本思想是:使用ActiveX控件,来构筑包括从与用户交互和适应COM的事务处理监视器到 Web服务器、全部实现自动化的机构。Active平台包括两大部分:Active Server和Active Client。

Active Server实际上是中间层。使用组件或Active服务器页面,来提供用于业务逻辑和主要应用处理的场所。ActiveServer的技术,其核心是 NT Server、Microsoft事务处理服务器、数据管理服务、目录服务、Web服务以及网络服务。

事务处理服务器是把线程产生 和数据库多重化等传统的TP监控功能与Microsoft的基于组件的编程模型结合起来。数据管理服务等Active平台的其他组件是用OLE DB和ODBC,访问DB2、Oracle、SQL Server等的数据源。目录服务是在DCOM(Distributed COM,分布式COM)的周围,提供目录服务层,这样使远程对象在网络上能相互搜索。Web服务以Internet信息服务器为中心进行构筑,它为服务器 上的Web应用开发,提供脚本生成(Scripting)机构。网络服务以DCOM为中心进行构筑,通过以同步MS-RPC为中介的网络,使之能够连接控 件。

Active Client是一种交叉平台。Microsoft的技术纵然是独家所有,但也希望将这种技术向多个OS开放。具体实施计划是使用脚本引擎 (Scripting Engine)。这种脚本引擎是由标准的HTML和带有Microsoft特色的Java虚拟机(JVM)、Microsoft的VBScript与 JScript所构成的。Active Client组装进了Microsoft的IE 3.0和4.0,通过ActiveX,可以变成用户的C/S应用的一部分。

从清一色采用Windows的企业用户来看,Active平台 可以提供坚固的、具有可缩放性的服务器应用开发平台。ActiveServer在TP监视器这类高端产品的场合,也利用常见的一些工具和技术。因此,小型 工作组和Intranet应用不会超越Active Server的能力。Active平台的目标机虽是异种机环境,但由于过分依赖IE,所以不能驱动客户端。尽管在一些非Windows平台上也推出了 Explorer,但最好的支持、最新版本的Explorer还是在Windows上。
三、ActiveX的进展 1.向分布计算扩充

COM的最初版本假定COM对象及其客户端是在同一个机器上运行(可以在同一个进程内,也可以在不同的进程内),DCOM是ActiveX家族中的重要成员。后来,它在Windows 95中也能使用。DCOM对于客户端制作COM对象、进行交互的方法没有做任何改变。

客 户端使用完全相同的代码,可以访问本地以及远程对象。但许多场合下,客户想使用少数的DCOM附件。DCOM备有分布式安全保密机制,提供认证和数据加 密。在1998年要发布的Windows NT 5.0中,要将Kerberos等安全保密协议,追加到DCOM中。DCOM已能够利用域名服务等简洁的目录服务,以用于搜寻在其他机器上的COM对象。 NT 5.0要追加对Active Directory的支持。Active Directory是基于域名服务和轻型目录访问协议的。
DCOM的劲敌,此前一直是OMG(Object Management Group)的CORBA(Common Object Request Broker Architecture)。它被组装进了Iona的Orbix和Visigenic的VisiBroker等产品中。不久前,另一种支持分散对象的技术 ——Java的远程方法调用出台了。无论是CORBA,还是DCOM,都能在多种语言写的对象间进行通信。而RMI却不同,它只限于在由Java实现的对 象间进行通信。显然,这是个制约。但RMI使用起来非常简单。另外,RMI的开发者可以用Java来设计协议规范。因此,在语言的功能上,可以做得浑然一 体。若写一个只处理两三个客户端的DCOM服务器,还是比较简单的。但是,要构筑一个高效处理几百、几千个客户端的DCOM服务器,则相当之难。

为 了便于编写可缩放的DCOM服务器,Microsoft发布了事务处理服务器(MTS)。MTS在支持事务处理的同时,也提供自动生成线索和智能对象的重 复使用等服务。MTS使可缩放服务器的制作变得相当简单。即使是无需事务处理的应用,使用MTS也有好处。实际上,Microsoft鼓励人们用VB来写 MTS应用。这与开发业务服务器的传统手法不同,所有的MTS应用,都是作为一个以上的COM对象来编写,且必须以DLL来实现。一般情况下,客户端看不 到MTS。客户端只管一如既往地制作、使用COM对象即可。

2.组件的标准化

基于组件的应用开发,其方法和组装电子装置一样,可以用已制作好的组件部件来构筑应用。桌面用的、基于COM的组件叫做ActiveX控件。所谓ActiveX控件不过是遵从一定的标准、与客户端交互的COM对象而已。

例 如,ActiveX控件必须通过Automation (即使用dispinterfaces)来公开方法。用这个被标准化的交互功能,可以在多个不同的上下文中,使用同一个控件。在这个标准接口的"幕后", ActiveX控件几乎是什么都能执行。现在,许多软件公司都能提供实现各种功能的控件。

ActiveX控件是作为DDL编写的,为此,必须装载到某个容器中。ActiveX控件的原型容器是VB,除此之外,还有多种容器可供选择。目前,一个非常重要的控件容器是Microsoft的Web浏览器Internet Explorer。
现在所谓ActiveX控件的那些内容,是实现许多方法所必须的。已经把它们从机器的本地硬盘移到了VB等容器中。几百KB和几MB的控件,似乎没 有什么大区别。但要将控件装载到Web浏览器时,很可能要通过速度很慢的电话线。现在,控件的大小已经是非常关键的问题。一旦要执行超过了某个限度以上的 控件,就会延长下载时间。因此,Microsoft规定:在ActiveX控件中,只能执行绝对必要的功能。
Apple和IBM推行的OpenDoc,曾是ActiveX控件的主要竞争对手。现在OpenDoc的赞助企业,已正式宣告中止资助。大部分与 Microsoft对抗的企业,转而支持JavaBeans(基于Java的组件结构)。ActiveX控件,基本上都是和Windows捆绑在一起、以 二进制机器代码发放的,而JavaBeans却不同,它在哪儿都能执行。这当然是有代价的。显而易见,只要不牺牲可移植性,就不可能完全、彻底地利用本地 环境。要编写从公共Internet上能下载的组件时,应优先选择JavaBeans。
桌面组件市场在持续、急速增长。其中绝大部分是以ActiveX控件构筑的(目前JavaBeans仍然是少数)。但服务器组件的标准化要落后一 些。在桌面上,Web浏览器、VB以及PowerBuilder这些编程环境,作为容器是强有力的。但服务器容器又该当如何呢?作为服务器上的组件容器, 事务处理服务器是一个较好的选择。
Microsoft的竞争对手,千方百计要阻止MTS和NT称霸市场。他们正在快马加鞭地制订服务器上的组件标准,其中最有前途的是 Enterprise JavaBeans。它是JavaBeans的扩充,并定义了事务处理服务器接口。Enterprise JavaBeans的支持者们,希望独立软件厂商不是将服务器组件作为COM组件来编写,而是要作为Beans来编写。
四、ActiveX的构筑工具
随着ActiveX控件的推广,ActiveX控件的开发工具逐日增加。由于ActiveX不依赖于语言,所以传统的开发工具基本上都能构 筑、配备ActiveX控件。最常用的有Delphi、PowerBuilder以及Visual Basic、Visual C++、Visual J++等。
1. 基本概况
用3GL开发ActiveX控件的方法有:①MFC (Microsoft Foundation Class,Microsoft基础类),②ATL(ActiveX Template Library,ActiveX模板库),③BaseCtrl Framework等。MFC最经典,采用MFC,可以使开发者不去关心接口,而是集中精力关注对象的动作。缺点是控件的规模较大且执行时DLL必须与容 器同时存在。ATL可利用模板生成代码。就是说,库和DLL无需与控件一起推出。在ATL中,需要从作为模板存在的几个基本类派生类。ATL也有缺点,即 接口的处理较难,应用中必要的接口,必须分别制作。另外,ATL不支持类向导(Class Wizard)。遗憾的是,没有使对象描述语言(Object Description Language)和接口定义语言文件、与用户代码自动同步的向导。BaseCtrl是个简便型库。与ATL非常相似,但无模板。实际上,由于 BaseCtrl过于简便,Microsoft并不支持它。在BaseCtrl中,带有几个万能控件(Skeleton Control)。BaseCtrl提供容易理解的ActiveX开发模型,但与ATL相比并不简单,且灵活性也不及ATL。目前看来,对于 ActiveX控件开发者来说,BaseCtrl是个"苦涩"的选择。

2. 开发工具
可制作ActiveX控件的、最初的工具是Microsoft的Visual C++。它可为ActiveX开发者提供最多的控件。Visual J++也可以制作ActiveX控件。

Borland 推出的两个工具(JBuilder和IntraBuilder)也非常令人瞩目。但是,用Borland的工具能制作ActiveX组件的, 只有Delphi 3.0和C++ Builder。Borland把Delphi的ActiveX开发功能,叫作Active Inside。它是将任意的Delphi Window做成ActiveX的形式。Active Inside备有配备在Web上的新控件。Delphi可以将控件链接到COM和DCOM。

PowerBuilder 5.0是改造成能用于ActiveX开发的、客户机/服务器开发工具。 PowerBuilder可以将Data Window(PowerBuilder应用开发的核心部分)作为ActiveX控件来配备。以使现在的PowerBuilder开发者,能使用 PowerScript编程语言等某些熟悉的功能。具有制作ActivX控件最好工具的,当属Microsoft。例如,若用Visual Basic 5.0,开发者就可使用可视化编程环境和本机的Visual Basic for Application语言,来开发控件。
五、ActiveX 的未来的确,Windows和Windows NT的世界,是ActiveX技术的最佳环境。但无论Microsoft如何卖力推进它的OS,也不能使所有的企业都变成清一色的Windows。因此, Microsoft要设法使COM、DCOM以及ActiveX家族的一部分,也能在其他OS上使用。现在,在Macintosh中,已经支持 ActiveX,其中也包含对ActiveX控件的支持。Software AG正在把这些技术移植到多个Unix和IBM的OS/390上。DEC和HP也打算将这些技术在自己的系统上使用,他们也是用移植Microsoft代 码的办法来实现的。

COM已成为Windows 95和Windows NT环境下基础软件的重要部分,但它的未来还有许多不确定的因素。例如,Microsoft是否能将COM作为多平台技术,让其继续存在发展下去?为了使 NT服务器能适合已有的企业,就必须要使DCOM等分布式服务也能在非Microsoft平台上应用。要解决这些问题, 需花费相当长的一段时间。另外, 基于CORBA的产品和Java的RMI,已成功地运行在多OS环境下。多平台DCOM出台得越晚,CORBA和RMI就领先越多。ActiveX控件和 JavaBeans的竞争前景如何?无论使软件运行在Web浏览器上也好,还是在另外的地方运行也好,总之,组件式软件(ComponentWare)将 是下一个软件开发的热点。

图文并茂 简单 ATL COM开发

1.打开vs2010,新建ATL COM 项目,如下图1
 
2.勾选 【支持COM+ 1.0】和【支持部件注册器】
 
3 添加了一个com项目,在项目名称上点击右键,添加类,如下图
 
然后打开如下窗口,选择ATL简单对象即可。
 
然后是如下窗口,在简称一栏中输入类名称FirstClass,其他输入框会自动填写,然后点击完成即可。如果出现提示【是否覆盖现有文件】,点击【是】即可。
 
4.切换到类视图(视图->类视图),选中刚才添加的接口IFirstClass,如下,然后右键单击【添加】à添加方法。
 
打开了添加方法向导,如下,输入方法名【Add】,在下方增加参数。
先增加两个输入参数:勾选【in】,选择参数类型LONG,输入参数名para1,点击添加。同样操作增加参数para2.
然后增加一个返回参数:勾选【retval】,选择参数类型LONG*,输入参数名result,点击添加。
 
点击完成即可。如果点击下一步,打开如下窗口,如果不需要填写信息,点击完成即可。
 
5.切换到解决方案资源管理器,打开IDL定义文件 FirstCom.idl,看到如下代码,就是定义的COM方法了。
interface IFirstClass : IDispatch{
         [id(1)] HRESULT Add([in] LONG para1, [in] LONG para2, [out,retval] LONG* result);
};
[
         uuid(77067637-4F17-4CBB-A12B-28979A8D21FB),
         version(1.0),
         custom(a817e7a1-43fa-11d0-9e44-00aa00b6770a,"{CB407CA1-C9ED-4A94-B505-91212F94FCED}")
]
6. 打开FirstClass.cpp 编辑方法逻辑如下:

// FirstClass
STDMETHODIMP  CFirstClass::Add(LONG para1, long para2, LONG* result)
{
         // TODO: 在此添加实现代码
         *result = para1 + para2;
         return S_OK;
}

7.至此,完成了COM编写,编译为dll,并自动注册到系统中。下面来调用一下刚才编写的COM,打开一个WPF项目,在项目文件上右击,选择【添加引用】,打开添加引用对话框,切换到COM选项卡,发现我们编写的COM已经在这里了,点击确定即可。
 
如果在COM选项卡里面没有看到,请使手工注册COM DLL,打开cmd,然后用Regsvr32注册。打开WPF项目的引用文件夹,如下,刚才添加的引用已经在这里了。
 
8. 使用WPF程序调试COM,编写代码如下:
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            FirstComLib.FirstClassClass firstClass = new FirstComLib.FirstClassClass();
            int ret = firstClass.Add(1, 5);
        }
    }
测试发现,ret=6,调试成功~!