在打算讲这篇文章之前我深思一个下午,打算分两篇来讲的,但是又怕读者看着嫌烦;其实稍微了解一点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组件加载到内容运行;这个 过程被我细化了,只要能说明原理就行了;