在打算讲这篇文章之前我深思一个下午,打算分两篇来讲的,但是又怕读者看着嫌烦;其实稍微了解一点ActiveX插件的朋友都能知道,这样一扯可能出现一堆问题;但是我还是决定通过简单的方式尽量让初学者少接触底层的东西包括OLE(对象连接与嵌入)、COM(组件对象模型)之类的概念,但是ActiveX插件在开发上有很高的技术要求,虽然.NET为我们封装了很好的实现途径,但是我们也总不能停留在,知自然而不知其所以然的层面上;今天这篇文章我大概构思了一下,我主要会由浅入深的去逐层的讲解,对一些概念性的东西,我会给出参考资料供大家去学习,由于它的发展历史我也就不去讲解了,主要是实现为主;如果喜欢刨根问底的朋友可以去查询相关的文章或者看一些关于OLE、COM方面的书籍,就算我们不从事相关开发,但是对于我们进行.NET互操作方面还是很有帮助的,也不至于让我们觉得.NET的局限性;本人向大家推荐一本OLE方面的好书:《OLE 2高级编程技术》
其实说起ActiveX插件大家都会想起Flash插件,对Flash插件就是一个很典型的COM组件,宿主在以OLE为容器的Web浏览器应用程序中,我们把这个OLE容器称为复合文档应用,复合文档应用程序在微软的系统到处可见如:Office就是一个很强大的复合文档应用程序,为什么要称为复合文档应用程序呢,是因为以容器为宿主的时候,可以进行任何应用集成开发,在office里面我们可以进行图表的编辑、Excel的编辑等等;在这个OLE中使用的对象严格意思上讲都是COM组件,对COM不了解的朋友可以去看一下《COM本质论》也是一本很好的书籍,其实COM就是组件对象模型,是二进制的组件,在任何平台任何语言之间都能使用;它是一套组件规范一套开发标准,大家都去遵守这个约定,才能使不同厂商生产的组件互相调用;而ActiveX插件就是一个COM组件,在早期的开发中对COM的开发是一种望而生畏的感觉,也许我们做.NET开发的程序的感觉开发组件DLL可能并没有多大难度,不需要去了解一些操作系统底层的东西比如:函数在编译过后重新编码对调用产生的影响,不同操作系统对可执行文件的内存分配回收等等问题,都需要开发组件的人了如指掌之后才能开发出出色的COM组件,然而在今天我们站在.NET这艘航母上,不需要害怕这些复杂的技术难题,微软为我们打开一扇通往平坦大道的大门,用最简单的方式去开发最复杂的东西,从某种角度讲是好事,坏事就是让我们越来越远离核心的东西; 这就要看每个人对技术的追求目标了;
由于.NET开发出来的东西都是属于托管的,所以不是正真意义上的二进制标准,这就牵扯到.NET平台调用的技术P/Invoke和互操作Interop技术,但是我们不了解也没关系,这不影响我们开发ActiveX插件,我只是给大家指一个方向;用.NET开发出来的东西要想完全替代COM组件,因为OLE容器只接受COM组件才能使用,所以我们的托管DLL文件怎样才能被OLE容器调用呢,就是通过.NET互操作COM来实现,我们开发的ActiveX插件要被浏览器这么一个大强的复合文档程序加载和使用的,所以我们得将托管的组件包装成非托管的等价的COM组件才行,.NET提供了CCW(COM可调用包装)的机制,将我们的ActiveX插件通过中间转换一下就可以使用了,理论的东西我就到此结束,我们开始动手做一个ActiveX插件吧;先看一下ActiveX插件的运行图:
1:
这是系统在运行过程中要经历的过程调用步骤,有助于我们下面的开发讲解;首先是浏览器接受到远程服务器返回的HTML文本,然后浏览器将HTML转换成DOM对象在通过GDI或者GDI+进行绘制渲染等界面呈现工作,发现在HTML中包含了对本地机器上的COM组件调用,通常也就是我们HTML中的object标签所定义的说明;在标签中会包含COM组件的唯一标识符GUID(全局唯一ID),在我们机器存在着成千上万个COM组件,只有通过GUID才能确定是哪一个组件,浏览器通过GUID到注册表中去查找这个COM组件在本机注册时的地址,得到地址后在将其COM组件加载到内容运行;这个过程被我细化了,只要能说明原理就行了;
下面我们进入到VisualStudio工具进行ActiveX插件开发,我们要新建一个项目这个项目必须得以DLL文件的形式存在,但是要是ActiveX插件必须得有界面啊;所以我们新建一个Windows窗体控件库项目:
2:
新建后会出现一个默认的用户自定义控件我们随便放一个按钮就行了,然后写点测试代码;
3:
每一个ActiveX插件都有一个入口地址,这就是COM入口地址;我们就拿我们上面的这个测试界面作为入口地址;我们切换到代码视图;
4:
我们在这个类的上面添加了两个特性,ComVisible是否对COM公开,这个特性的意思就是说我们的组件是否能用于COM组件的相关调用查找;如果没有这个特性我们的组件是不能用作COM调用的;GUID特性就是用来为我们的这个类型确定一个部署到客户机器的唯一标识符;这个GUID可以通过VisualStudio工具栏中的功能自动创建;我们还差一步就成功完成了这么一个庞大的工程了,我们右击项目选择属性会出来下面这个界面:
5:
将为COM互操作注册勾选上,作用就是为了能与COM等组件进行相互调用了,在我们程序目录中会生成一个和组件名称一样的tlb文件,必须有这个文件我们才能使用这个插件,tlb文件是一个类型库文件,作用就是将托管DLL文件的所有信息导出成COM规范的接口文件,在这个tlb文件中定义了COM的调用约定;由于COM和.NET组件无法直接交互所以只能通过tlb文件来确定我们的托管的DLL文件中定义哪些东西;我们编译一下;我们还差一个HTML文件,这个文件随便是来自哪里都可以,这个HTML文件里面要定义调用我们这个ActiveX插件才行;
6:
我红色箭头标记的地方就是Object标记所定义的调用代码,ID就是为调用的ActiveX插件起的一个名字便于在页面中通过JS进行互操作;CLASSID是要调用的ActiveX插件在用户机器上的GUID唯一标识符;CODEBASE如果用户机器上没有安装这个插件则让浏览器帮忙下载的URL地址;其他的标记就是和普通的HTML一样的了;在此我穿插一下,所有的HTML标记最终都会被转换成实实在在的对象,而不是我们所谓的HTML纯文本;
我们保存HTML文件,并且打开这个文件就能看见ActiveX插件被加载运行了;
7:
我这里之间简单的讲解了一下ActiveX插件的基本创建过程,其实ActiveX插件的功能很强大,对B/S一些的功能只能通过插件来解决如:大文件上传、视频采集、照片动态采集等等;插件在部署的时候一定要注意,部署到用户机器上的时候,在属性栏中有一个文件注册方式,一定要选择为COM注册这样才能在注册表中添加相应的节点;ActiveX插件开发大概就讲完了;希望讲的还算清晰明了;