这个问题不光是在5中有 我用delphi7的时候也出现了同样的问题,这次一定要做个记录,浪费了一天的时间找到的
首先,我们来看看
VB
写的
ActiveX
控件在
Delphi 5
下面的奇怪表现。
例如:我们用
VB
编写了一个控件
UserTest
(为简单起见,我们只导出一个类即用户控件),一个属性
TestName,
一个方法
TestMethod
。然后将其编译成一个
ActiveX
控件,注册并导入
Delphi5
的开发环境(以上步骤如有未清楚之处,请查阅各类参考资料,肯定有标准答案),到目前为止,看来一切正常。
然后,我们习惯的把控件拖放到窗体上,调整大小,在属性窗口中为属性赋值,或者在代码中也是一样,非常正常,好用的很。但是,下面问题来了,如果您兴致勃勃的去调用了那个
TestMethod
,那么您将得到一个古怪的异常
“Ole Error 800a01a9”
,然后程序退出,而且非常不幸的是,您将无法跟踪到这个异常,在
Delphi
中或是
VB
中都是,当然如果您对汇编很在行的话,您可以跟着
Delphi
的调试窗口一步一步往下
……
当我第一次碰到这个问题的时候,我几乎是愤怒的,因为无论是
MicroSoft
或是
Borland
,对该错误都没有任何解释,也没有任何可以查找的资料。我只好跑到常去的几个论坛,当然最主要的还是
CSDN
,在
VB
版和
Delphi
版中四处搜索类似的问题,然后非常遗憾的是,只有类似的问题,而没有答案,一个大客户就用的这个开发工具,我在测试了几乎所有
Windows
上的开发工具和开发环境(包括桌面和
WEB
)后,惟独将
Delphi
忘记了。
剩下的两天里,我几乎是满世界乱跑,给所有的朋友打电话,询问
Delphi
方面的高手是否知道这个情况,最后,我从
Google
上搜到了一个链接,可惜的是现在我忘记了那个链接的具体位置,但是我得到了一个近乎
Magic
的方法(发现者是这么称呼它的):
一个手工修改
Delphi
导入
VB ActiveX
控件后产生的代理类型库
XXX_TLB.PAS
(这里
XXX
指的是控件的类名
)文件的方法可以解决这一问题。举例说明:
有一个
VB
写的控件
UserControl1
,在
Delphi
中导入后产生两个文件,其中一个
UserControl1_TLB.PAS
就是我们所要修改的文件。
在文件中查找
类似
FintF:
_UserControl1
;
Function GetControlInterface:
_UserControl1
;
和
property ControlInterface:
_UserControl1
read GetControlInterface;
GetControlInterface;
以及
procedure TUserControl1.CreateControl;
procedure DoCreate;
begin
Finf:=IUnknown(OleObject) as
_UserControl1
;
End;
Begin
If Finf=nil then DoCreate;
End;
Function TUserControl1.GetControl1Interface:
_UserControl1
;
Begin
CreateControl;
Result:=Finfl;
End;
请注意:这里红色标出的
_UserControl1
要
全部换成
_ UserControl1Disp
,
如果编译不成功的话,请将编译警告中报出的
_UserControl1
全部换成
_UserControl1Disp
,编译即可,这样在调用控件的方法时便不会出现上述的致命错误。
感谢这个伟大的发现,我只能这么形容它,否则可能到现在我还要在这个圈子里套不出来,或者就是使用另外的工具重新开发这个控件(我难以想象这个工作量会有多大,又或者它可能还会存在其他的兼容性问题)。