开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 23103|回复: 198
收起左侧

[易语言纯源码] 一个成熟的易语言编写COM模板

    [复制链接]

结帖率:100% (1/1)
发表于 2022-8-29 22:32:31 | 显示全部楼层 |阅读模式   广东省佛山市
分享源码
界面截图: -
是否带模块: -
备注说明: -
本帖最后由 htpidk 于 2022-8-29 22:41 编辑

一直以来,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:
1.png
图中指出的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这个数组里去
4.png

以上就是编写自己COM组件时需要在模板里修改的几个地方,简单吧。修改完后就可以添加自己需要的方法然后生成COM组件载体dll了,注意我们所有实现的方法第一个参数都必须是一个整数型,而且我们不要去使用它,也就是这个参数必须要有但是不要去使用。
10.JPG
这里我们就实现了一个方法叫ceshi,并且它没有参数(虽然这里有一个整数型参数this,但是前面说了这个参数每个我们实现的函数都要有并且不能使用,所以这个ceshi函数相当于没有参数)

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

这里面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的VC98\Bin目录下有一个VCVARS32.bat的批处理文件,因为是绿色版的原因,这里面有两个地方需要修改
7.png
画红线的地方,改成自己VC6.0里对应的路径

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

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

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


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


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


1:易语言调用
11.JPG
12.JPG



2:C++调用
13.JPG

3:网页调用(只能IE模式才能调用COM,chrome内核浏览器不支持,所以以前很多政府网站和银行都只能用IE打开,因为U盾那些都是COM实现的ActiveX组件)
15.JPG

压缩包里提供了一份纯模板源码,两份从模板修改的COM源码和对应的idl文件,都只实现了一个名叫ceshi的方法,“ComTemplate1无参信息框例子”编译生成的COM组件里的ceshi方法没有参数,“ComTemplate2有参信息框例子”编译生成的COM组件里的ceshi方法有一个文本参数
COM.rar (27.74 KB, 下载次数: 181)

点评

IDispatch集中guiidstringchar = #IUnKnownGiid 或 guiidstringchar = #IDispatchGiid 或 guiidstringchar = COMCLSID后面的guiidstringchar = COMCLSID改成guiidstringchar =InterFaceID   广东省深圳市  发表于 2022-9-19 14:22
idispatch_addref和idispatch_release那里有点问题,没有考虑到多个COM对象的问题,不影响使用,有能力的可以修复下,或者等我有空了再修复   广东省广州市  发表于 2022-9-12 17:41
修改VCVARS32.bat批处理文件时不止画红线的两个地方需要修改,还有下面的MSVCDir路径也需要修改成自己的,漏了补充下   广东省深圳市  发表于 2022-8-30 10:21
吴涛说,你把我的活都给干了,我干什么   安徽省合肥市  发表于 2022-8-30 08:55
你把吴涛的活都给干了   安徽省合肥市  发表于 2022-8-30 08:52

评分

参与人数 32好评 +28 精币 +385 收起 理由
w589321 + 1 + 2 感谢分享,很给力!~
※逍遥游※ + 1 感谢分享,很给力!~
手机号码专卖 + 1 + 2 新技能已get√
猥琐小胖子 + 1 + 4 开源精神必须支持~
kk2apple + 1 + 2 支持开源~!感谢分享
zhifu3158 + 1 新技能已get√
llxx123 + 1 + 2 太牛逼了
gto250 + 1 + 2 有没有更多的例子,返回文本,数字,数组之类的
易语言新新手 + 1 + 2 支持开源~!感谢分享
zhongyayong + 2 吴涛差点直呼外行了(滑稽)
1051496412 + 1 + 2 开源精神必须支持~
易语言资源网 + 1 + 5 开源精神必须支持~
吃泡面加不起蛋 + 1 + 1 干货,已收藏,有时间看看
ppppzj + 1 + 2 开源精神必须支持~
他乡遇故知 + 1 + 2 YYDS~!
fengyishen + 1 强得恐怖如斯
该死dē蚊子 + 1 + 2 太好了,最近研究这个com头疼好几天。
2576605471 + 1 + 3 支持开源~!感谢分享
hxznhf + 1 + 5 支持开源~!感谢分享
pipi9 + 1 + 2 YYDS~!
远赴 + 1 + 2 支持开源~!感谢分享
hipxh + 1 + 1 支持开源~!感谢分享
kyo9766 + 2 开源精神必须支持~
阿杰大大 + 1 + 3 精彩文章希望继续努力
项目部006 + 1 + 300 奉上小小红包希望笑纳
福仔 + 1 + 20 YYDS~!
冰点 + 1 + 5 感谢分享,很给力!~
气质征服一切 + 1 + 2 支持开源~!感谢分享
fjgh + 1 + 2 支持开源~!感谢分享
李泽勇2 + 1 + 2 开源精神必须支持~
szxiao + 1 + 2 YYDS~!
zytlj + 1 新技能已get√

查看全部评分


本帖被以下淘专辑推荐:

结帖率:100% (1/1)

签到天数: 20 天

 楼主| 发表于 2022-8-30 10:20:22 | 显示全部楼层   广东省深圳市
修改VCVARS32.bat批处理文件时不止画红线的两个地方需要修改,还有下面的MSVCDir路径也需要修改成自己的,漏了补充下

补充内容 (2022-8-31 23:05):
zcCOM和卸载COM的批处理运行时右键管理员权限运行,否则不一定能将信息写进zc表
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 20 天

 楼主| 发表于 2022-9-4 14:24:05 | 显示全部楼层   广东省深圳市
易语言怎么接收返回值的例子,返回整数和文本,其他的自己依葫芦画瓢吧

1.JPG

2.JPG

3.JPG

4.JPG

6.JPG

5.JPG

回复 支持 反对

使用道具 举报

结帖率:60% (3/5)

签到天数: 22 天

发表于 2024-11-6 03:29:30 高大上手机用户 | 显示全部楼层   广西壮族自治区柳州市
qslkjadhslkjds 发表于 2024-11-2 17:25
HRESULT FindPic(long x1,long y1,long x2,long y2,BSTR pic_name,BSTR delta_color,double sim,long dir ...

variant对应易语言的变体型,但是易语言又特坑,编写接口函数时用非基础类型作为形参应该是取不了函数指针,variant*的形参只能用整数,传进来一个变体型指针,变体型其实是个结构体,前两个字节存的子类型,整数VT_I4对应常量应该是2,中间6字节保留,后8字节就是实际数值戓数据指针,直接写入内存把反回值类型和数值写回去不就行了
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)

签到天数: 11 天

发表于 2024-11-4 12:29:38 | 显示全部楼层   河北省石家庄市
有人会吗,他这个帖子  怎么返回多个变量,有会的加Q1373390976
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)

签到天数: 11 天

发表于 2024-11-4 12:28:04 | 显示全部楼层   河北省石家庄市
贴主,怎么返回变量X,Y  
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 4 天

发表于 2024-11-4 10:57:58 | 显示全部楼层   河北省石家庄市

需求返回变量X,Y

本帖最后由 564561988 于 2024-11-4 11:00 编辑

请问谁会写 返回变量X,Y
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)

签到天数: 11 天

发表于 2024-11-2 17:25:54 | 显示全部楼层   河北省石家庄市
        [id(6)] HRESULT FindPic(long x1,long y1,long x2,long y2,BSTR pic_name,BSTR delta_color,double sim,long dir,[in,out] VARIANT* x,[in,out] VARIANT* y,[out,retval] LONG*);


请问易语言怎么写返回XY
回复 支持 反对

使用道具 举报

结帖率:100% (2/2)

签到天数: 22 天

发表于 2024-6-5 01:18:03 | 显示全部楼层   湖南省衡阳市
成功了,非常棒。方法绑定并成功调用 请问楼主 可以加入类和属性绑定吗。
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 4 天

发表于 2024-4-10 22:45:48 | 显示全部楼层   浙江省杭州市
新技能已get√
回复 支持 反对

使用道具 举报

结帖率:33% (2/6)

签到天数: 17 天

发表于 2024-3-21 13:09:30 | 显示全部楼层   广东省湛江市
感谢分享,很给力!~
回复 支持 反对

使用道具 举报

结帖率:60% (6/10)

签到天数: 2 天

发表于 2024-2-8 23:27:43 | 显示全部楼层   浙江省台州市
本帖最后由 飞灵 于 2024-2-8 23:49 编辑

无法创建对象可能跟常量支持库版本不对有关
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表