Delphi使用VB编写的ActiveX控件全攻略

原创 2004年02月17日 17:51:00
Delphi使用VB编写的ActiveX控件全攻略
前言
       在最近几周的工作里,始终被一个头疼的问题所困扰,那就是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

手把手教你用VB制作ActiveX控件

随着控件在可视化编程中地位地位提高,控件也成了编程中最重要的一部分。许多VB编程者也许苦于没有好看的控件,今天登高望远来教大家如何制作ActiveX控件。 一、新建工程       1.选择Acti...
  • qq_33582668
  • qq_33582668
  • 2016年06月11日 19:41
  • 4181

Delphi使用VB编写的ActiveX控件全攻略

Delphi使用VB控件全攻略前言       在最近几周的工作里,始终被一个头疼的问题所困扰,那就是VB6编写的ActiveX控件在Delphi环境下存在着诸多稀奇古怪的问题,几经周折,终于在搜索了...
  • holydiablo
  • holydiablo
  • 2003年11月06日 00:29
  • 915

delphi中ActiveX 和 Web

http://book.77169.com/data/web5302/20050228/20050228__3692503.htmlActiveX 和 Web在Windows 操作系统下,有一个重要的...
  • leixg
  • leixg
  • 2010年05月13日 16:42
  • 3728

一个用VB编写ActiveX自定义控件的例子

以做一个带背景图片的label框为例  1.首先选择添加一个用户控件……这个要怎么添加我就不多说了吧  然后在用户控件的界面上添加一个label一个image,同时将label1置为顶层(bring ...
  • cncco
  • cncco
  • 2009年08月16日 08:03
  • 1853

Delphi2007 下安装ActiveX控件

此英文文章来自codegear官方网站,但是是讲在BDS2006 下如何安装,我在delphi 2007下用此方法,一样通过,原文如下 Description:How to import an Act...
  • lee576
  • lee576
  • 2007年09月03日 19:44
  • 3872

ActiveX控件中全局变量的一种用法

在一个程序中,用到了好几个相同控件的实例,现在希望能通过某种方法来唯一的标志这些控件实例,以便能为每一个控件提供一个正确的配置文件,这是件很容易的事,但问题是并不希望控件增加什么ID,Name之类的属...
  • xiaoqiqixiao
  • xiaoqiqixiao
  • 2006年01月11日 12:34
  • 2234

VB6.0 ActiveX 控件开发详解 [第一章:创建工程]

前言         在CSDN的VB论坛上,我总是能够看见有人这样问“有没有这样的控件,一个列表框,每一个项前面有一个按钮”(这是例子),又或者见到这样:“怎么样做一个ActiveX控件?”,诸如此...
  • JiLuoXingRen
  • JiLuoXingRen
  • 2011年08月03日 18:19
  • 25524

Delphi使用VB控件全攻略

前言    在最近几周的工作里,始终被一个头疼的问题所困扰,那就是VB6编写的ActiveX控件在Delphi环境下存在着诸多稀奇古怪的问题,几经周折,终于在搜索了几乎全部的论坛、资料后,找到了针对不...
  • retty85
  • retty85
  • 2007年02月26日 23:13
  • 586

c++调用vb6.0制作的activex dll

本文将介绍在vs2008 中C++ 调用vb6.0 生成的activex dll。具体的源代码可以从以下链接下载:http://download.csdn.net/detail/xsjm206/409...
  • xsjm206
  • xsjm206
  • 2012年02月26日 21:08
  • 2846

Delphi下的COM接口編程(ActiveX Library)

在較早的時候,我的博客里已經有關于COM編程的有關知識(http://hi.baidu.com/yueyun889/blog/item/53ad2c1208b6f950f919b8ee.html),不...
  • lailai186
  • lailai186
  • 2012年11月16日 14:18
  • 2985
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Delphi使用VB编写的ActiveX控件全攻略
举报原因:
原因补充:

(最多只允许输入30个字)