最近在研究COM,看到论坛上关于COM事件挂接这方面的资料非常少,就尝试写个模块。
刚开始想把全部代码写到一个类里,奈何类里面取函数指针,使用汇编各种头痛,写出来不是事件不触发,就是触发后程序闪退。
最后把一部分代码写到程序集里,轻松多了,测试也算正常了
COM中事件应该分为两类,
(1) Interface (IUnknown) VT表前3个成员固定
QueryInterface 0
AddRef 1
Release 2
后面
事件1 3
事件2 4
事件n
.....................
事件触发直接按TV表调用指定事件成员,这个比较简单,
(2) IDispatch 继承 IUnknown VT表前7个成员固定
QueryInterface 0
AddRef 1
Release 2
GetTypeInfoCount 3
GetTypeInfo 4
GetIDsOfNames 5
Invoke 6
后面
事件1 7
事件2 8
事件 n
.......................................
事件触发首先调用分发函数 Invoke 传入事件子程序的DISPID等 再由Invoke调用DISPID对应的事件成员,这个稍为复杂点,要自己实现Invoke
经过两天的奋战,终于把模块写出来,能不能用也没有深度测试,大概问题是不大的。
测试程序挂了3个对象的事件
首先是常用的Winhttp.WinhttpRequest.5.1,这个对象是有事件的,只有在异步调用的时候才会触发
用工具杳看了Winhttpcom.dll中的4个事件定义
然后是VB6网络控件 Winsock (MSWinsock.OCX) 7个事件
再然后是微软的脚本引擎 ScriptControl (msscript.ocx) 2个事件
测试程序
Http异步调用,访问网页,数据接收完成触发 Winhttp_OnResponseFinished 事件
Winsock 随便连接一个服务器,触发了Error 错误事件
ScriptContorl 添加了不是脚本的字符同样触发了Error错误事件