网页脚本中无法响应ATL事件的解决办法
提示:纯技术文章,我花了将近两天的时间才解决,发出来希望能为遇到此类问题的人解惑,转载请注明出处(asnowwolf.blog.hexun.com)
学VC没多久,遇到一个问题:自己写的ATL组件触发了一个事件,却无法被脚本响应。于是开始着手解决这个问题,步骤如下:
1.先写了一个测试页面,以便简化问题,防止其他因素的干扰
2.用有问题的ATL组件来测试,仍有问题,说明不是脚本写错
3.新建一个MFC的ActiveX组件,可以正常响应,说明问题可能出在ATL中
4.注意到新建ATL对象的时候有几种ATL类型,可能适用的是Simple Object、Full Control、Lite Control三种,出问题的这个属于Simple Object,于是尝试其他两种类型,发现Lite Control同样有问题,Full Control却正常。
5.它们三者的区别在于实现了不同的接口,Full Control最多,Lite Control次之,Simple Object最少。
6.建立一个Full Control,逐一去掉它实现的接口,测试减少到什么时候无法正常响应事件,说明那个应该是关键接口
7.去掉 IProvideClassInfo和IProvideClassInfo2之后,事件无法响应,说明这两个接口很可能就是所找的关键接口
8.为Simple Object增加了对这两个接口的实现:
在继承部分增加一句:
public IProvideClassInfo2Impl<&CLSID_TestCtrl, &DIID__ITestCtrlEvents, &LIBID_TEST4Lib>,
在BEGIN_COM_MAP中增加两句:
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
之后能够正常响应事件
至此问题解决。
分析:
经查MSDN,接口IProvideClassInfo的作用是提供类型信息接口ITypeInfo,那么,它在脚本中起什么作用呢?
我们知道,VB和脚本由于无法构建VTable,所以都是采用后绑定的方式工作的,也就是说,它们在调用的时候才临时根据名字去找该调用哪段代码。它怎么才能找到这段代码呢?唯一能够为它提供足够信息的,就是ITypeInfo这个标准接口。所以,对象才必须实现这个接口。