


版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Visual Basic COM 基础讲座之简介 世上无难事,只要肯登攀 ,所以你要有信心成为一个 COM程序员,而且你一定能。事实上,我们每次设置文本编程控件的 Text 属性时,就已经在使用 COM,同样在 DAO数 据控件运行 MoveNext方法时,甚至在使用 VB控制字时,也都是在使用 COM。那么,什么是 COM呢?首先, COM是一种通信的方式。例如,就像我们的电视遥控一样。当我们按下某个频道按钮时,电视频道立马切换;而 当我们按下开关按钮时,电视立即关闭等等。其实,我们并不关心它们是怎样工作的,我们 只知道按下按钮就能产生某个动作就可以了。程序的原理也是一样的。 当改变文本编程
2、控件的 Text 属性时,我们并不知道其中的原理, 也许系统内部会调用几十个 API 函数也说不定?但对于用户来说,则只关心文本编程控件中 显示的文本就可以了。其次, COM是一种重用代码的方式。使用 COM的最大好处是一旦建立 COM的通信方式后,可以方便地在任何地方使用多次。 例如,当用户创建一个用于显示日期和时间的 COM组件后,就可用于任何程序中的任何地方。 不仅 VB应用程序、 Excel 程序可以访问,而且 C+应用程序也可以访问它。所以, COM组件的代码可重用性是最主要的。再次, COM是基于实际对象的。用 COM创建的大多数组件是基于实际对象的,这就意味着一旦组件被创建,其使
3、用是相 当容易的。试想一下,如果我们在计算机系统中再添加一个用户,又有哪种添加方式如 Customer.Add 那样简单,是添加数据处理代码包、算法,还是向应用程序添加较大的数据库 DLL?很显然, COM就支持这种简单操作。所以, COM是一种通信方式、一种代码重用方式以及基于实际对象的。本教程的以后部分中将简单讨论 COM和 VB的相关内容,这包括类的创建, 以及如何将类 转换成一个实际对象。虽然,这里的内容太过简单,但却是以后COM编程的基础。VB COM基础讲座之创建第一个COM对象让我们直接来开始创建第一个真正的 COM对象,它将被用于那些 ActiveX 程序中。具体步骤如下:启动
4、 Visual Basic ;我们将看到一个 New Project 对话框,其中有几个与 ActiveX 相关的选项图标。下面来 解释一下:ActiveX DLL 创建一个包含类的 .DLL 程序,这是我们将要采用的选项;ActiveX EXE 创建一个包含类的 .EXE程序,以后将讨论这个类型;ActiveX Control 添加一个工程,允许自己创建用于 toolbox 中的控件。这里不去讨 论它。ActiveX Document EXE 创建一个基于 Web页的.EXE 程序,这里也不去讨论。ActiveX Document DLL 创建一个基于 Web页的 .DLL 程序,由于与我们
5、的主题甚远, 所以自然也不去讨论它。顺便说明一下,如果在工程列表中没有上述选项,那么你可能使用了 Visual Basic 的学 习版。当然,在上述那么多选项中,我们真正感兴趣的是 ActiveX DLLs 和 Active EXEs 。等会 再来讨论后一种,这里先看看第一种!选中ActiveX DLL 项; 单击OK按钮; 这样,一个 ActiveX DLL 工程就建立好了。我们之所以创建 ActiveX DLL 是准备将它作 为一个前端服务器,它基于 Northwind 数据库中的 Customers 表的 (Northwind 数据库是随Visual Basic 一起发行的,位于 VB9
6、8文件夹中 ) 。这也就是说,我们后面一定会处理 Customers 信息,但那时我们仅仅需要对类的调用, 而不想过多地停留在数据处理代码的纠缠中。当然,我们得首先创建这个类。虽然 COM能使编程更容易一点,但这个类的构造还是比 较困难的。尽管如此,在深入数据库之前,先来对 ActiveX 程序中的名称作一些修改。将类的 Name属性改为 Customers ;选择Project-Project Properties菜单,在弹出的对话框中,将工程名改为Northwind ;现在再来使类与数据库相连:选择 Project-References 菜单;在弹出的对话框中,选择 Microsoft A
7、ctiveX Data Objects 2.1 Library,单击 OK按钮;该 引用 允许用户处理一个数据库,当然现在都使用 COM对象来处理了。下面将围绕 相应的记录集而展开:在我们的类中添加下列代码:这是一个用于访问数据库的记录集对象。 当然,当其他开始使用该类时,我们希望记录集对象能和数据库建立连接,而当类使用 结束后,与数据库的连接能断开。基于这种思想,其代码如下:在代码窗口中,将 Object 组合框中当前的 (General) 项改为 Class ; 在右边的组合框中,确保当前项为 Initialize ; 代码窗口中将出现:当类刚开始时,所有这里面的代码都会被执行,类似于表单
8、中的Form_Load事件在 Initialize事件中键入下列代码: Set rs = New Recordset rs.ActiveConnection = Provider=Microsoft. & _ Jet.OLEDB.4.0;Data Source=C:Program Files & _Microsoft Visual StudioVB98Nwind.mdb; & _ Persist Security Info=Falsers.Open select * from customers, , adOpenKeyset, adLockOptimistic这里不需要任何与该类相关的代码,
9、它只是使用 Visual Basic 通用的 ADO数据库处理代 码,该类中的代码是用来如何与数据库建立连接的。需要说明的是,如果 Northwind 数据库 Nwind.mdb 不在 C:Program FilesMicrosoft Visual StudioVB98 文件夹,那么必须将 ActiveConnection 字符串内容作适当修改!当类开始时, rs 对象负责与数据库建立连接,但当类对象结束后或程序关闭它时,我们 应该使该连接断开。编程时,我们使用 Terminate 事件,它与 Form_Unload 非常相似的。下面来加入数据库关闭的代码:从 Object 组合框中选择 Cl
10、ass ,从 Procedure 组合框中选择 Terminate ; 在 Terminate 事件中,添加下列代码:这就是我们添加的又一段简单代码,它只是简单地关闭数据库,然后将 rs 设置为 Nothing 。这样, rs 就会被有效删除。好了,本节就到这里。下一节中,我们将继续添加代码用来处理数据中的记录集。VB COM基础讲座之添加属性和方法面,我们添加一个属性来让用户获取 CustomerID 字段的值,其相应的示例代码如下:Public Property Get CustomerID() As StringCustomerID = rs(CustomerID)End Propert
11、yPublic Property Let CustomerID(NewValue As String) rs(CustomerID) = NewValueEnd Property显然,该属性的 Get 操作只是简单地返回 CustomerID 字段的值,相应地, Let 操作是 将CustomerID 字段设置一个新值。换句话说,属性中有两个部分: getting 和letting ,事实上可能还有另外一个 setting 操作。但对于不同场合来说,我们总需要 Get 和 Let 来进行读和写的操作。这里所引起注意的是,在上述属性过程中,应该对某些值进行必要的检测。例如,在调 用 Let 属性
12、时,用户可能有如下操作:ObjectName.CustomerID = HALFI该 Let 属性操作后, CustomerID 等于新的字符串 HALFI 。但当查看 Northwind 数据库 内容时,我们会发现 CustomerID 字段的字符长度不能超过 5。如果用户有这样的操作:ObjectName.CustomerID = HALFISTORE则出现数据库操作错误。虽然,可以通过错误句柄来处理这个问题,但是如果能在代码 中检测 NewValue的长度岂不更好?如果该值超过 5 个字符,我们既可以通过裁剪取共前 5 个 字符,也可以忽略这个新的字符串而弹出一个错误提示。但这里,我们采
13、用后一种措施。在我们的类中添加下列代码:Public Property Get CustomerID() As StringCustomerID = rs(CustomerID)End PropertyPublic Property Let CustomerID(NewValue As String)If the length of NewValue is greater than fiveIf Len(NewValue) 5 Then. then raise an error to the programusing this classErr.Raise vbObjectError + 1,
14、 CustomerID, _Customer ID can only be up to five & _characters long!Else. otherwise, change the field value rs(CustomerID) = NewValueEnd IfEnd Property好了,在完成下列步骤之前,我们已经为添加方法花费了不少时间。在我们的类中添加下列代码:该 Update 方法只是简单地调用记录集对象的 Update 方法来更新记录。下一步,我们将用一个很小的样例程序来测试这个属性和方法,在测试时还将使用特定 的技巧来追踪类和程序的运行。VB COM基础讲座之类的
15、测试现在就来测试前面创建的类。启动按 F5 运行程序;在弹出的属性对话框中,选中 Wait for Components to Start( 工程时等待创建部件 ),然后按 OK按钮;这时,类就会被激活,其他程序就可使用它的功能。再次运行 Visual Basic 另一个实例;创建一个新的 Standard EXE 工程;选择 Project-References 菜单;浏览对话框中可引用的列表项,可以发现一些额外的组件。选中 Northwind 列表项;Northwind 就是前面创建的 ActiveX 工程。单击OK按钮;现在添加一些代码来使用上述工程:在 Form1 表单中添加一个命令按
16、钮;为命令按钮添加下列代码:Dim Test As Customers Set Test = New Customers MsgBox Test.CustomerID Set Test = Nothing该代码首先创建一个新的 Customers 对象,然后显示 CustomerID 信息,最后将 Test 对象 置为 Nothing ,并关闭它。按 F5 键运行测试程序;需要说明的是,当运行时出现 invalid reference 错误提示时,肯定哪些地方有问题。 这时可按下面步骤重新来一次:(1) 在测试工程中去掉 Northwind 引用;(2) 重新启动 Northwind 工程;(
17、3) 在测试工程中添加 Northwind 引用,再运行! 单击表单中的命令按钮; 这时运行时可能需要几秒钟,毕竟还要做一些如数据库连接等工作。但是,除了一开始的停留外,后面的调用就快得多了。程序将显示包含 ALFKI 的消息对话框关闭测试程序。现在,我们来看看程序背后究竟发生什么。将插入符移动到 MsgBox Test.CustomerID 这条语句上;按 F9;该语句显示为红色,用来标记一个断点。当代码运行时,它会停留在这里。按F8 将单步运行此语句,并移动到下一句代码上。按 F5 再次运行测试程序;单击命令按钮;流程将停留在 MsgBox这条命令上。按 F8,慢慢单步执行各条语句;将会看
18、到系统在两个 Visual Basic 中来回切换,显示出不同属性的处理过程。结束后,关闭测试程序。下面再对前面的工程进行测试。这一次, 我们不仅获取 CustomerID 的值,而且还设置这 个值。将命令按钮的代码改为:Dim Test As CustomersSet Test = New CustomersTest.CustomerID = KARLY该代码首先设置 CustomerID 字段,然后更新记录集,最后显示出 CustomerID 属性,其 结果应该是设置的 KARLY。假如愿意,仍然可以按 F9高亮显示 Test.CustomerID = 这条语句,然后按 F8单步运行来查看
19、其工作情况。至此,我们已经成功地创建并测试一个简单的基于数据库的类。但是,还没有对customerID 的字符串长度作测试,如果其长度超过 5 个字符,看看会发生什么? 下一步,我们将扩充并改进这个数据库类首先添加类的几个特征:其他的属性、一些方法甚至一两个事件。 其相应的代码如下:Dim WithEvents rs As RecordsetPublic Event RecordsetMove()Private Sub Class_Initialize()Set rs = New Recordsetrs.ActiveConnection = Provider=Microsoft.& _Jet.
20、OLEDB.4.0;DataSource=C:Program Files & _Microsoft Visual StudioVB98Nwind.mdb; & _Persist Security Info=Falsers.Open select * from customers, , adOpenKeyset, adLockOptimistic End SubPrivate Sub Class_Terminate()rs.CloseSet rs = NothingEnd SubPublic Property Get CustomerID() As StringCustomerID = rs(C
21、ustomerID)End PropertyPublic Property Let CustomerID(NewValue As String)If the length of NewValue is greater than fiveIf Len(NewValue) 5 Then. then raise an error to the programusing this class, by runningErr.Raise vbObjectError + OurErrorNumberErr.Raise vbObjectError + 1, CustomerID, _Customer ID c
22、an only be up to five & _ characters long!Else. otherwise, change the field value rs(CustomerID) = NewValueEnd IfEnd PropertyPublic Property Get CompanyName() As VariantCompanyName = rs(CompanyName)End PropertyPublic Property Let CompanyName(ByVal NewValue As Variant) rs(CompanyName) = NewValueEnd P
23、ropertyPublic Property Get ContactName() As VariantContactName = rs(ContactName)End PropertyPublic Property Let ContactName(ByVal NewValue As Variant) rs(ContactName) = NewValueEnd PropertyPublic Property Get ContactTitle() As VariantContactTitle = rs(ContactTitle)End PropertyPublic Property Let Con
24、tactTitle(ByVal NewValue As Variant) rs(ContactTitle) = NewValueEnd PropertyPublic Property Get Address() As VariantAddress = rs(Address)End PropertyPublic Property Let Address(ByVal NewValue As Variant) rs(Address) = NewValueEnd PropertyPublic Property Get City() As VariantCity = rs(City)End Proper
25、tyPublic Property Let City(ByVal NewValue As Variant) rs(City) = NewValueEnd PropertyPublic Property Get Region() As VariantRegion = rs(Region)End PropertyPublic Property Let Region(ByVal NewValue As Variant) rs(Region) = NewValueEnd PropertyPublic Property Get PostalCode() As VariantPostalCode = rs
26、(PostalCode)End PropertyPublic Property Let PostalCode(ByVal NewValue As Variant) rs(PostalCode) = NewValueEnd PropertyPublic Property Get Country() As VariantCountry = rs(Country)End PropertyPublic Property Let Country(ByVal NewValue As Variant) rs(Country) = NewValueEnd PropertyPublic Property Get
27、 Phone() As VariantPhone = rs(Phone)End PropertyPublic Property Let Phone(ByVal NewValue As Variant) rs(Phone) = NewValueEnd PropertyPublic Property Get Fax() As VariantFax = rs(Fax)End PropertyPublic Property Let Fax(ByVal NewValue As Variant)rs(Fax) = NewValueEnd PropertyPublic Sub AddNew()rs.AddN
28、ewEnd SubPublic Sub Update()rs.UpdateEnd SubPublic Sub CancelUpdate()If rs.EditMode = adEditInProgress Or _rs.EditMode = adEditAdd Then rs.CancelUpdateEnd IfEnd SubPublic Sub MoveNext()rs.MoveNextEnd SubPublic Sub MovePrevious() rs.MovePreviousEnd SubPublic Sub MoveFirst() rs.MoveFirstEnd SubPublic
29、Sub MoveLast()rs.MoveLastEnd SubPublic Function FindByCustomerID(CustomerID As String) As Boolean Uses the Find method to locate customers with a matching CustomerID.Returns True value is customer(s) foundDim varBookmark As Variantrs.MoveFirstrs.Find (CustomerID= & CustomerID & )If rs.EOF = True The
30、nFindByCustomerID = False rs.Bookmark = varBookmarkElseFindByCustomerID = TrueEnd IfEnd FunctionPublic Property Get EOF() As BooleanExample of a read-only propertyNo Property Lets hereEOF = rs.EOFEnd PropertyPublic Property Get BOF() As BooleanAnother example of a read-only propertyBOF = rs.BOFEnd P
31、ropertyPrivate Sub rs_MoveComplete(ByVal adReason As ADODB.EventReasonEnum_,ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, _ByVal pRecordset As ADODB.Recordset)Reacts to the recordset MoveCompletemethod - raises event with each move RaiseEvent RecordsetMoveEnd Sub需要说明的是:迄今为止,我们仅仅是在一
32、个类中添加代码。当然,也可以选择 Project-Add Class 菜单来向工程添加多个类,而且还可利用 collections 使这些类工 作在一起。但是在这里,我们仍然想用一个类来处理一个数据表。将上述类的代码复制并粘贴到自己的类中,下一节将讨论该程序的编译VB COM基础讲座之全面测试这一次,我们不用 Visual Basic 来测试前面的程序,而是先来编译:选择File-Make Project1.exe 菜单;择要保存的文件夹,单击 OK 按钮;退出 Visual Basic ;运行刚才编译过的 .EXE 文件;当表单出现时,试试打开一个 customer ,然后对其修改并单击 O
33、K 按钮。再打开刚才的 customer ,看看其资料是否被修改?结果应该是这样,因为 ActiveX DLL 会自动将结果保存 在数据库中。现在,让我们静下来想一想刚才做过的事件。我们只用了几条简单的语句就建立了一个 自己的数据库应用程序, 虽然这里只使用了 COM一点功能, 但却使得应用程序变得如此容易。关闭已测试完的应用程序;如果上述过程比较顺利的话,那么我们再做这样的测试:打开 Northwind 工程;假如对 Northwind 工程作了某些修改,那么还需要重新编译:菜单;选择File-Compile Northwind.dll选择和上次保存 Northwind.dll 相同的文件夹
34、,以便覆盖原来的文件,单击 OK 按钮; 需要说明的是,如果编译时出现错误,那肯定在程序中有一些不对的地方。关闭所有正 在运行的程序,然后再重新试一试。编译后,退出 Visual Basic ;再次运行 Project1.exe ;天啦,居然会有错误信息,类已不再支持原来接口。这就是我们做的一种测试,当重新编译 ActiveX 工程时,使用它的程序就会被支解。解决上述问题的一种办法是将 Project1 文件打开并重新编译。 但是假如工作组中有两百个员工,这就是说,我们得把重新编译好的工程和新的 DLL 分发到这两百个员工手上。你能受得了吗? 不,不能这样做。我们必须搞清楚错误产生的原因,以及
35、弄明白为什么我们的工程不能 和最新的 DLL一起工作,难道是兼容性的问题吗?本教程的最后一部分将详细探讨这些内容。VB COM基础讲座之 ActiveX EXEs到现在为止,本教程一直讨论基于 ActiveX DLLs 中的类的内容,但是没有一本教程 不说明与 DLL相似的 ActiveX EXEs 。所以,想在这里实际编写一个 ActiveX EXE工程。事实上,它和 ActiveX DLL没有太 大的区别,甚至没有区别。在启动 Visual Basic 后选择 ActiveX EXE就可创建,然后像 以前一样构造自己的类。但这里不想再作更详细的讨论,因为 ActiveX EXE和 Acti
36、veX DLL除了在运行时有一些微 小区别外,其他都相同。它们的区别首先表现在它们的 进程空间 的不同。所谓 进程空间 是用于运行、处理和 存取的一块计算机内存。 任何 Windows程序,如 Microsoft Word等,都有自己的 进程空间 , 它很像程序的桌面那样。当使用 ActiveX DLLs 工程运行时, DLL 是在使用它的程序的进程空间中运行的,而ActiveX EXE是在进程空间外面工作的。但是, ActiveX EXE还有自己的 桌面 。这究竟如何 理解呢?假如, ActiveX DLL 变得不稳定或意外受损时,使用它的应用程序常常出现蓝屏的死机 现象,而在 EXEs中却
37、不会发生,因为它有自己的 进程空间 ,即使被破坏,也仅仅是桌面受 损,当然用户程序应该很好地去修复它。其次,它们的区别还表现在装载的速度上。由于 DLL 是直接装载到已存在的进程空间, 所以它的速度非常快。而 EXEs由于还要分配自己的进程空间,所以速度上相对慢一点上述两点区别可以说是它们真正的区别。总之,如果使用不同的 Windows工具来实现相应的 ActiveX 组件,那么相应的工程类型 就应该有所不同。例如,若使用 MTS,则应创建 DLL工程,若使用 DCO,M 则应创建 EXE工程。 当然,即使现在不理解这此缩写字母的含义,我们也不必担心。因为它们是针对高级用户的, 并用于 COM
38、远程的工具组件。以后有机会再来给出相应的教程。这里再来分析第二点的区别。如果现在需要创建这样的一个程序,它不断地检测一个数据库是否有什么改变。那么我 们想到的是在程序中使用一些 timer( 计时器 ) ,每隔 10 分钟激发一次并检测该数据库。但 问题来了,在该进程空间的其他所有代码都要被停止运行直至数据库检测完毕。而 ActiveX EXEs伟大之处,就在于它有自己的进程空间。所以在其中添加的计时器也只 会工作在自己的进程空间中而不会影响其他使用它的程序。 也就是说, 对于前面的工程来说, 若使用 ActiveX EXE 来检测数据库,则不会停止其他使用它的程序的运行;即使需要从其他 程序
39、中返回一个消息,也可以通过其他事件而获得。需要说明的是,运行代码远离正规程序而通过事件与使用的应用程序会话的方法称为 异步处理 。通常当需要对 e-mail 或数据库作定期检查时,或当运行一个长的报表以及计算 大的统计数据时,我们就需使用这种异步处理方式。不怕你惊讶的话,我们可以将前面论述的内容总结成这样的一句话:ActiveX DLLs 是在进程内运行,而 ActiveX EXEs 是在进程外运行 。好了,下一节将创建并测试一个自己的 ActiveX EXE 工程,并使用大家还不太熟悉的 异步处理 技巧。然后,提出一个称为 实例的有意义的概念,最后指明怎样获得更多的 COM 知识使自己达到一
40、个新的水平。VB COM基础讲座之测试 ActiveX EXEs本节将创建并测试自己的 ActiveX EXE 程序。示例中将使用这样一个组件, 它是一个有效的文件探测器。 大约每隔 60 秒检测指定文件 的存在性。如何该文件存在,该组件激发一个事件来调用应用程序,如果不存在,则另作处 理。当然,如果将所有代码写到 ActiveX DLL 工程,则运行时程序代码将被挂起直到文件检 测代码运行完毕为止。由于 ActiveX EXE工程拥有自己的进程空间,代码运行时会自我协调、 异步处理,从而不会使其他程序代码停顿。下面就来创建:新建一个 ActiveX EXE 工程;工程名设为 File ;添加的类名为 FileCheck ;下一步,我们需要构造一些用于每隔 1 分钟左右检测文件的代码。 这里将在 ActiveX EXE 工程插入一个带有计时器的表单。但该表单不会被显示,因为我们只是使用上面的计时器控 件每隔 1 分钟左右来检测文件,如果相应的文件被检测到,则激发一个事件。选择Project-Add Form ;在表单 Form1中添加一个计时器;在表单代码中添加下列变
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- FMS课件教学课件
- 信息流账户优化知识培训课件
- 信息技术培训知识课件
- 八年级生物上册 第六单元 第二章 认识生物的多样性说课稿 (新版)新人教版
- 2024年五年级数学下册 6 圆 圆的周长(1)说课稿 苏教版
- 2025年安全员考试题库及答案
- 信号集中监测系统课件
- ESD术课件教学课件
- ERP知识培训内容课件
- 第二课 时间是个魔术师说课稿小学心理健康六年级上册辽大版
- 防水工程质量保证书
- 大额资金使用管理办法
- 业务激励方案61170
- 家电行业售后维修服务管理流程
- 迈克尔杰克逊课件
- 2024年煤炭工业矿井设计规范
- 替莫唑胺耐药机制-深度研究
- 二级中医医院评审专家手册
- 遗产继承案例分析题单选题100道及答案
- DB43∕T 925-2014 保障性苗圃建设规范
- 绿色施工实施策划方案
评论
0/150
提交评论