一起来讨论VB与COM......
Bardo 2002-03-15 08:10:05 说起COM我首先想起的是在《Inside Com》一书中所讲的,类实际上也是一种结构,用VB的语言来说,类即是Type的扩展。那么类扩展了什么?很简单,类是在结构中加上了函数(方法)和事件。再进一步,函数可以为虚函数,这样,就可以象定义结构那样定义类了。于是,这样的类即是一个空类,又称为父类。有了空类,在VC中通常是用构造函数来对类初始化,使其成为一个对象。而VB则用的是COM的接口委派继承而产生新的对象。于是这又回到了COM这个本质的问题。
我们现在难以想象,在COM以前究竟是什么方法能使应用程序实现二进制共享。但是,有些事实是记得的。早期的VB控件,其扩展名是VBX。其中的X是同时指16进制与扩展这两个含义,说穿了仍是二进制扩展。为何要扩展,目的是为了成为共享组件。到了VB4.0,那时还不是COM,但己有了OCX,据说原含义是OLE CONTROL EXTENTION。
而现在我们不妨再看看:VB能用的文件的扩展名有:OCX,DLL,TLB,OLB,EXE,而这些实际并不以扩展名而决定其是否为COM,但是如果我们只要在资源管理器中查看一下文件属性,即可以知道:
OCX:ActiveX DLL
DLL: ActiveX DLL
DLL: 应用程序扩展(当然前者在2000中说明也是这样)
TLB:Type Libaray
OLB: Object Libaray
EXE: ActiveX Exe
Exe: 应用程序(当然前者在2000中说明也是这样)
我们可以发现,只要是Libaray则VB即可以使用!!同样,只要带上ActiveX则VB即可以引用或添加为部件。
另一个很奇怪的是:通常VB中引用的ActiveX以后,常用的方法是:Set或CreateObject,如:
Dim oSome as fSome.oMenber
Set oSome = New fSome.oMenber
或者
Dim oSome as fSome.oMenber
Set oSome = CreateObject(fSome.oMenber)
如果你用过VC,那一定会想到,你可以用类向导新建类,选From Type Libaray, 然后即可选择一个VB的DLL。 这时最简单的则是用CreateObject创建对象后调用。在VBScript中同样也是用这一种方法。我想这三个CreateObject一定存在差别,差别在何处?
我还想到,一定有很多人不知,在Visual Studio 6.0的第三张安装盘上有这么两个工具:一个是在:
:\COMMON\TOOLS\VB\IDGEN\
说明是:
Both GUIDGEN and UUIDGEN are tools for generating globally unique identifiers known as GUIDs. GUIDS are commonly used in OLE to identify classes (CLSID) or interfaces (IID.) These utilities are included with VB for developers who want to generate IDL (Interface Description Language) or ODL (Object Description Language.) IDL and ODL are used with the MIDL.EXE and MKTYPLIB.EXE tools to generate type libraries that can be used with VB.
另一个是在:
:\COMMON\TOOLS\VB\UNSUPPRT\TYPLIB
这是一个将对象定义语言的文件编译成TLB扩展名的文件以使VB可用。
这两个工具是在COM之前的,也就是说,COM之前就有了某种模式。由此我在想,那个《Hardcore of Visual Basic 5.0》的作者是不是用这些工具为WIN32 API做了个对象库?好象不是,那么,可能就与MSDN中KB中的Make Type Libaray那个例子有关!
回过头来,再说COM与VB,一说起COM编程,一定是OCX或DLL,然而,OCX中却很难看出前述基本的COM,实际上应当与Visual FoxPro中的叫法一样——容器类,即控件是通过容器类来继承的。所以,如果你要自定义控件,则有两个途径:创建ActiveX控件工程,或者在你的工程中加上UserControl类。这是一个秘密,VB5界面上有此菜单,VB6.0界面上没有,实际上是可以加进去的。
那么通过什么才能看出前述基本的COM呢?以下即是一个最简单的例子:
新建一个ActiveX Dll 工程Project1,
在Class1中加入以下代码:
Option Explicit
Public Function doHello() As String
doHello = "Hello,world!"
End Function
编译,然后在另一工程Project2并引用Project1.dll,以下是调用代码:
Private Sub Form_Load()
Dim ctest As New class1
MsgBox ctest.doHello
End Sub
如果将前者看作是Type,则:
Type Class1
Option Explicit
Public Function doHello() As String
doHello = "Hello,world!"
End Function
End Type
当然,这样是不可执行的。
(未完持续)
**********************************************************************
很希望大家能帮助我解决以上诸多疑问,同时也希大家共同讨论,因为COM对于VB
还有:异步通知,多线程,网页文档,......