COM模板易语言源码一直以来,COM编程对大多数人都是比较难以理解的,要想真正的理解COM的本质首先要熟练C++,然后还需要对模板有一定程序的了解,因为编写COM的ATL框架里使用了大量的模板,只有熟练了C++和模板后才能读懂COM里各种实现的源码,不管是IUnknown、IClassFactory还是IDispatch等各种接口里各种方法的具体实现原理,还是类型库、连接点等实现原理,都只有在读懂了ATL源码后才会恍然大悟,才知道这里是怎么实现的,为什么要这样实现,也只有读懂了ATL源码才能知道COM实现类厂、创建COM的一系列过程。windows系统里大量使用了COM组件包括ActiveX也是在COM的规范上实现的,平时使用到的很多功能其实都可以通过调用COM来实现。因为使用易语言的人群大多都不会C++,所以就有了今天这个源码和教程。

说的有点远了,易语言一直以来都是只能调用COM而不能编写COM,以前在易语言官方论坛上看到过有一些人的尝试,也写出了简单的DEMO,但是都不是比较成熟的框架或模板,需要编写者对COM有一定程度的了解才能修改,一般不熟悉COM的人是修改不了也使用不了的。最开始本来是打算写一个增强COM功能的支持库,但是后面还是想写一个编写COM的模板比较好,经过两天时间的编写和调试才把这个模板写出来,说一下在这个模板上编写自己COM组件的几个注意事项

1:
网上下载一个绿色版的VC6.0,压缩包只有50多M,放心,下载VC6.0不是让你用它编写程序,只不过是需要用到它里面的两个工具,开始我是打算自己把这两个工具从VC里扣出来的,奈何依赖太多了,扣的不完整,使用时报错,所以直接下载一个VC6最好。

2:

图中指出的4个地方,编写不同的COM组件需要修改,其中etclsid、setinterfaceid和settypelibid等3个函数的参数是一个GUID/CLSID,每个COM组件这3个GUID都必须是不同的且不能和其他COM组件的GUID相同,这个可以用工具来创建,最好不要自己瞎写,不注意的情况下容易重复,工具截图如下,如果安装了精易的美化界面库后就自带了,在易语言的“工具”菜单里,当然也可以在网上自己下一个,VC里也自带了这个工具,这个也就是第一点说的让大家下载VC6.0的原因之一,里面有这个创建GUID的工具。除了etclsid、setinterfaceid和settypelibid等3个函数的参数GUID需要修改外,还有setprogid这个函数的参数EFirstCom.1字符串也需要该,随便你怎么改,只要不和其他COM组件的相同就行,易语言创建COM对象时会用到这个,例如大家经常使用到的“对象.创建 (“WinHttp.WinHttpRequest.5.1”, )”,网页访问对象里就会用这个命令创建一个COM对象,这里的WinHttp.WinHttpRequest.5.1就是这么个东西。最后再说一次,这4个地方都必须修改且不能和其他COM组件的重复

3:
IClassFactory程序集里的CreateInstance函数里有一个地方需要增加,就是你自己实现了COM的哪个方法,就必须在图中画圈的地方把这个方法的地址加入到class这个数组里去

以上就是编写自己COM组件时需要在模板里修改的几个地方,简单吧。修改完后就可以添加自己需要的方法然后生成COM组件载体dll了,注意我们所有实现的方法第一个参数都必须是一个整数型,而且我们不要去使用它,也就是这个参数必须要有但是不要去使用。

这里我们就实现了一个方法叫ceshi,并且它没有参数(虽然这里有一个整数型参数this,但是前面说了这个参数每个我们实现的函数都要有并且不能使用,所以这个ceshi函数相当于没有参数)

4:
大家按照上面说的修改了模板后就可以编译生成COM组件了,此时还不能使用,还有一个东西需要编译生成,这个东西就是类型库,这也是让大家下载VC6.0的第二个原因,编译类型库时需要一个idl文件,我提供了VC6.0版的idl文件的模板,大家在里面进行修改就行,修改按照下面我说的来

这里面ABC三个地方的GUID改成和源码里的一样,A处改成模板里setinterfaceid (“{97BE627C-10AC-46A3-8039-1118B48F855E}”)这个函数的参数,B处改成模板里的settypelibid (“{A65A210D-B0B5-483F-9823-E151F0DED7D4}”) 这个函数里的参数,C处改成模板里setclsid (“{B982539B-94D6-426E-B643-90A90E50C14D}”)这个函数的参数,模板里这3个GUID是什么,这3处就修改成什么。D处就是我们自己实现的方法,这里我实现了一个简单的接口,里面实现了一个名叫ceshi的方法,这个ceshi方法没有参数,注意:这里方法名前面的[id(1)]就是我们实现的方法的序号,返回值都必须是HRESULT类型,假如我们除了实现ceshi这个方法外,还实现了一个叫msg的无参数方法,那么D处就要加上一句[id(2)] HRESULT msg(void);记得这里序号要改成2,方法无参数就用void表明,另外如果方法有参数,记得带上参数的类型,例如再增加一个方法kk,这个方法有一个参数为整数型,那么就在D处加上[id(3)] HRESULT kk(LONG);LONG就代表了参数是整数型,其他的还有BYTE代表了字节型,SHORT代表了短整数型,FLOAT代表了小数型,DOUBLE代表了双精度小数型,BSTR代表了字符串类型。暂时这个模板就支持这几种类型,最后再增加一个方法fun,有三个参数,第一个参数是整数型,第二个参数是小数型,第三个参数是文本型,那么就在D处继续加上[id(4)] HRESULT fun(LONG,FLOAT,BSTR);记住编号要从1开始逐渐增加,不能两个方法的编号相同,另外COM中的字符串都是宽字符,所以如果我们编写COM时使用到了文本型参数,记住不要用易语言中的“文本型”,而是要用一个指向宽字符的指针也就是整数型来代替(压缩包里有例子),但是我们用易语言调用COM对象时不用提供宽字符文本,只用提供普通的文本型参数就可以了。总之就是实现COM时涉及到文本的一律用宽字符,调用COM时则提供普通文本参数,易语言内部会将ASCII字符串转换为宽字符再去调用。

经过上面说的修改步骤后就可以将idl文件生成类型库了,需要用到VC6.0,在VC6.0的VC98Bin目录下有一个VCVARS32.bat的批处理文件,因为是绿色版的原因,这里面有两个地方需要修改

画红线的地方,改成自己VC6.0里对应的路径

修改完VCVARS32.bat后就可以准备生成类型库了,在VC98Bin这个目录里打开一个CMD窗口,运行VCVARS32.bat

接着在这个CMD窗口里继续操作,假如前面我们改写的idl文件名字叫11.idl,我们要生成的类型库名字叫xx.tlb(生成的类型库名字要和前面编译生成的COM文件dll名一样),那么用命令midl 11.idl /tlb xx.tlb就可以了

这样就生成了类型库xx.tlb

最后把之前编译生成的COM文件dll和类型库tlb放到一个目录,注意,dll文件名最好和tlb文件名一样,否则模板里还有其他地方需要修改,假如前面编译生成的COM文件dll叫ff.dll,那么就要把这里生成的类型库名xx.tlb也改为ff.tlb。

经过上面操作后就算完工了,用“注册COM”就可以注册这个COM了,当然事先需要把“注册COM”里的COM文件路径改成你自己的。

============================================================
上面是生成COM文件过程,接下来我们来调用它,分3种调用方式,易语言调用,C++调用,网页调用(调用之前必须保证已经注册了这个COM到系统)

发表回复

后才能评论