CSDN博客

img beibeiyang

ActiveX控件相关知识~

发表于2004/10/9 10:37:00  1128人阅读

2004年10月9日10:37:56

控件是做什么的?
http://www.seven-color.com/problem/problem5.htm


   
控件的原形就是能执行一定功能的函数.
    Function[函数]->OCX[OLE自动机]->ActriveX[活动组件]函数因为通用性不好,因人而异,移植困难.OLE遵循一定协议.可以,但各种语言编写的OCX还是不太兼容.ActiveX则是目前较为完整的方案了.在OOP[面向对象编码]中,控件就是,被封装起来的一组类,每个类中有一些属性与方法[可以看成函数的集合].

ActiveX控件的创建
作者:顾岱鸿
http://vbeden.xg88.com/vbtech/activex/page_1/file4.htm

1)概述

  ActiveX是一个Microsoft的术语,它指的是一组包括控件,DLL和ActiveX文档的组件,它通常是以动态链接库的形式存在,因此必须在一个叫容器的独立执行软件中运行。这样的容器包括Authorware、Delphi,Visual Basic,Visual C++,Internet Explorer和Access等等。

  ActiveX控件数据输入和函数功能执行都必须通过容器,因此ActiveX控件和容器都必须支持一些特定的接口协议。根据Microsoft 相应的规格标准,ActiveX控件应具备如下的性能机制。

属性和方法:ActiveX控件必须提供属性的名称、方法的名称及参数,通过这项机制容器可以存取和改变ActiveX控件的属性参数。

事件:ActiveX控件由这项机制通知容器在ActiveX控件中发生的事件,比如属性参数的改变,用户按下鼠标左键等。

存储:容器由这项机制通知ActiveX控件存储和提取有关信息数据等。

  ActiveX控件只要在Windows的Registry数据库中注册后,就可以像其他Windows应用程序一样发挥各自的功能。

  ActiveX控件是一个模块化的灵活对象,如果某个应用程序或网页需要增加一项特殊的功能,无须重写整个程序,只要灵活地插入一个具有此项功能的ActiveX控件即可实现。ActiveX的优势还在于它的动态可交互性,用户可以动态地在使用过程中,通过改变它的属性和参数,在应用程序中实现自己的特殊要求。

  也许有的读者会问:目前在市面上可以找到各种各样现成的ActiveX控件,还有没有必要自己创建ActiveX控件呢?关于这个问题很容易解释,现有的控件种类是很多,功能也比较齐全,问题是有许多时候会遇到这种情况:使用现成的控件虽能完成任务,但自己需要的一些特性(属性、事件或方法)该控件却没有提供,还需要自己手工写代码来实现,而这些特
性偏偏在自己的应用系统中又经常会用到,为了避免大量的重复劳动,一劳永逸的办法就是在创建自己的ActiveX控件。

  目前可以使用Visual Basic或其它开发工具创建 ActiveX控件。无论按照哪种标准,Visual Basic都是计算机历史上最为成功的(同时也是最流行的)编程语言,其中最令人兴奋的特性就是可以创建用户自己的控件并可以像其他控件一样应用于支持 ActiveX控件技术的应用程序中。下面通过一个具体实例来阐述如何在Visual Basic 6.0(中文企业版)下进行
ActiveX控件创建。

 2)创建ActiveX控件的步骤

  使用Visual Basic编程语言编写过应用程序的用户,一定非常熟悉诸如TextBox、Label和Data等控件。要利用这些控件,可以将它们绘制在窗体中,通过属性,方法和事件控制它们的行为。当用户创建自己的ActiveX控件时,除了确定属性、方法和事件以外,用户是在创建一个相似的对象。当创建了自己的ActiveX控件以后,就可以在其他Visual Basic 工程中使
用它,就像使用TextBox控件一样。可以在能使用ActiveX控件的任何应用程序或开发工具(包括其他Visual Basic工程、Authorware或者Microsoft Internet Explorer)中使用自己的控件。

  在Visual Basic中创建一个ActiveX控件不同于创建一个Standard EXE
应用程序。因此当创建一个新控件时,一般应遵循的步骤是:

(1)确定控件将要提供的功能。因为ActiveX控件类似于一个独立的对象,所以需要明确这个对象的目的,希望它在屏幕上有什么样的外观?使用此控件时,需要什么属性、方法以及事件用于应用程序中?
(2)设计控件的外观。
(3)设计控件的接口,即属性、事件和方法。
(4)创建由控件工程和测试工程组成的工程组。
(5)通过把控件和或代码添加到 UserControl 对象中来实现控件的外观。
(6)实现控件的接口和功能。
(7)编译控件部件(.ocx 文件)。

下面按照上述步骤建立一个可直接显示数据库内容的DataListView控件。

3)具体实现方法

(1)确定DataListView控件的功能

  标准的ListView控件在显示数据库记录时还存在一些不足,如必须编写大量的代码等,DataListView通过在ListView的基础上添加部分功能而弥补了ListView的不足,因此它除了本身固有的属性、方法和事件外,添加了如下成员:

◆ DataServerName属性 -- 确定所操作的数据库服务器。
◆ DataBaseName属性 -- 确定所操作的数据库。
◆ AdministratorName属性 -- 确定操作数据库的管理员名称。
◆ PasswordName属性 -- 确定操作数据库的管理员口令。
◆ ShowDataBase方法 -- 显示Select命令所执行的数据库操作结果。
◆ErrorDataBase事件 -- 当遇到错误的数据库操作时引发该事件。

(2)设计控件的外观

  DataListView由于仅包含一个ListView控件,所以其外观没有太多需要考虑的问题。如果要创建的控件是多个控件构成,或新控件不包括任何现存控件即完全从头开始创建一个全新的控件的话,则外观问题是一个很重要的问题。

(3)设计控件的接口,即属性、事件和方法

  对ListView控件所作的改进是为了让ListView控件支持数据库的内容显示,以便在所有能支持ActiveX控件的应用程序中使用。通过添加用户自己的属性DataServername、DataBaseName、AdministratorName、PasseordName和方法ShowDataBase等可以实现这项功能。DataListView的其他属性、事件和方法都和标准ListView一样。

(4)创建由控件工程和测试工程组成的工程组

◆启动一个新的ActiveX控件工程。
◆按下CTRL+T 组合键或者选择【工程】|【部件】菜单选项,显示【部件】对话框,在【控件】选择框中选择Microsoft Windows Common Controls 6.0。
◆ 选择【工程】|【引用】菜单选项,显示【引用】对话框,在【可用的引用】选择框中选择Microsoft ActiveX Data Objects 2.0 Library。
◆在UserControl窗口中添加一ListView控件,ListView控件的左上角位置为0,0。
◆设置ActiveX工程和UserControl控件属性值,如下表所示。

  条目             设置
 工程类型           ActiveX控件
 工程名称           DataLV
 工程描述           通过ADO,使得ListView控件能够直
                接操作数据库
 UserControl 的Name属性    DataListView
 UserControl 的Public属性   True

◆保存这个工程。
◆选择【文件】|【添加工程】菜单选项。然后添加一个标准EXE工程。建  立该工程的目的是为了在创建ActiveX控件时不断地进行测试。

  此时已建立了一个由控件工程和测试工程组成的工程组,下面就可以正式开始创建DataListView控件。

(5)实现控件的外观

  确定控件外观的方式取决于当前控件的创建模型。如果要创建一个用户绘制控件,那么必须自己在UserControl_Paint 事件过程编写代码来完成所有的绘制工作,同时还需要确定何时绘制控件,以便在需要的时候调用UserControl的Refresh方法来产生Paint 事件。如果是改进一个现有控件,那么只需正确地将组成控件放置在UserControl上即可。

  由于DataListView控件仅包含ListView一个组成控件,那么只需简单地在UserControl1上绘出一个标准ListView控件,控件名为缺省的ListView1,即可完成外观绘制工作。

  为了在使用控件时,使ListView控件和自己绘制的空间相匹配,必须建立UserControl的Resize事件过程。Resize事件过程的代码如下:

Private Sub UserControl_Resize()
  ListView1.Left = 0
  ListView1.Top = 0
  ListView1.Width = UserControl.Width
  ListView1.Height = UserControl.Height
End Sub

  仅四行代码的Resize事件过程是简单控件的用户界面的所有必须的代码,其目的是使ListView控件和UserControl对象有相同的尺寸。

(6)实现控件的接口和功能

  这是整个创建过程中最核心、最重要也是最复杂的步骤。对于创建控件的每一属性、事件和方法均需逐一实现。

◆创建DataServerName属性

  要创建DataServerName属性值,首先需要添加一个在内部存贮属性值的局部变量。要做到这一点,在UserControl对象的Genaral Declarations通用声明语句中创建此变量。如下所示:

Dim m_DataServerName As String

  接着需要创建称为DataServerName的新属性,可以通过手工输入Get和Let过程,或者选择【工具】|【添加过程】|【类型】创建这个新属性。DataServerName属性的代码相当容易理解。当置DataServerName属性的值时,Property Get过程仅将局部变量的存贮内容取出来。当设置DataServerName属性值时,Property Let过程将为局部变量赋予一个有效值。以下是两个Property过程的代码:

Public Property Get DataServername() As String
  DataServername = m_DataServerName
End Property

Public Property Let DataServername(ByVal New_DataServerName As String)
  m_DataServerName = New_DataServerName
  PropertyChanged "DataServerName"
End Property

  需要注意的是在Property Let过程中,有一个PropertyChanged方法,它的功能是通知容器(可以理解为存放所有属性的单元)属性值已变更,需产生一个WriteProperties 事件,来保存新属性值。事实上不仅在Property Let过程需要调用PropertyChanged方法,在UserControl的代码模块中无论何时改变了ActiveX控件的某个属性值,均需调用该过程,以保存属性的变化。

  注意Property DataServerName方法的用法,此方法与ReadProperties
和WriteProperties事件在一起使用。

  此时需要使用用户控件的InitProperties事件指定此属性的初始值:

Private Sub UserControl_InitProperties()
  m_DataServerName = m_def_DataServerName
End Sub

  即使用户没有设置初始值,这些代码也会确保设置了一个初始值。

  至于DataBaseName、AdministratorName、PasseordName 属性的创建过程跟DataServername属性的创建过程完全一样,这里就不再重复叙述。

◆使用PropertyBag对象

  用户还需要为WriteProperties和ReadProperties事件创建代码,从而保护DataServername、DataBaseName、AdministratorName、PasseordName属性在设计阶段的属性值。这两个事件都使用PropertyBag 对象保存和检索DataServername、DataBaseName、AdministratorName、PasseordName属性的值。PropertyBag对象能够保持DataServername、DataBaseName、
AdministratorName、PasseordName的设计值。具体实现代码如下:

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
  m_DataServerName = PropBag.ReadProperty("DataServerName",
            m_def_DataServerName)
  m_DataBaseName = PropBag.ReadProperty("DataBaseName",
            m_def_DataBaseName)
  m_AdministratorName = PropBag.ReadProperty("AdministratorName", m_def_AdministratorName)
  m_PasswordName = PropBag.ReadProperty("PasswordName",
            m_def_PasswordName)
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
  Call PropBag.WriteProperty("DataServerName", m_DataServerName,
            m_def_DataServerName)
  Call PropBag.WriteProperty("DataBaseName", m_DataBaseName,
            m_def_DataBaseName)
  Call PropBag.WriteProperty("AdministratorName",
          m_AdministratorName, m_def_AdministratorName)
  Call PropBag.WriteProperty("PasswordName", m_PasswordName,
          m_def_PasswordName)
End Sub

  由于这两个过程是针对"容器"对象的,因此所有属性值的保存和读取都通过这两个过程来实现,而不是每个属性都需要单独的两个过程。其中,PropertyBag就是"容器对象"的名称。

  WriteProperty方法有三个参数:第一个字符串标识需要保存的属性,第二个参数是需要保存的值,最后的参数是属性的缺省值。

  ReadProperty 方法需要两个参数:一个字符串用来保存属性的名称,另一个为缺省值。

  在窗体上绘制ActiveX控件的那一刻,就会开始执行ActiveX控件的代码。在控件设计过程中,将DataServername、DataBaseName、AdministratorName、PasseordName属性的默认值设置为:

Const m_def_DataServerName = "lyc"
Const m_def_DataBaseName = "pubs"
Const m_def_AdministratorName = "sa"
Const m_def_PasswordName = ""

  当然,也可以在程序运行时多次修改它。控件的正常行为是当程序终止时恢复其默认值,这样增加了保持属性的两种独立状态的要求。

  简言之,如果在设计阶段改变了一个属性值,那么控件必须得到这个新值,而不是使用默认值。相反,如果在程序运行时改变属性值,那么当返回设计状态时,控件必须检索此属性值。

  PropertyBag对象允许ActiveX控件存贮有关它自己的属性值,使它能执行这个动作。PropertyChanged 方法会通知用户已经改变了一个属性。通过了解程序的状态以及是否调用了PropertyChanged方法,VB 就可以激发WriteProperties和ReadProperties事件。

◆为ShowDataBase方法编写代码

 ShowDataBase方法实现在ListView控件中显示Select命令所执行的数据库操作结果。在其具体实现过程中采用了 ADO(ActiveX Data Objects)的数据存取方法。ADO的主要特点是使用更加容易,访问速度更快,而对磁盘和存储容量的要求更小,ADO支持建立各种客户/服务器模式与基于Web的应用程序,具有远程数据服务RDS(Remote Data Service)的特性,通过RDS能够在一次往返中将服务器端的数据传送到客户端的应用程序或Web页面中,并在客户端对数据进行处理后,立即更新服务器端的数据。采用ADO所基于的OLE DB技术,可以对电子邮件、文本文件、数据表格等各类数据通过统一的接口API接口进行存取,是远程数据存取的一个主要发展方向。ShowDataBase方法具有一个字符串参数,但无任何返回值,具体代码如下所示:
Public Sub showdatabase(ssql As String)
Dim AdoDatabase As New ADODB.Connection
Dim AdoTable As New ADODB.Recordset
Dim scnn As String
Dim response As String
Dim I As Integer
On Error GoTo errorhandle
scnn = "Provider=SQLOLEDB;Data Source="
& Trim(m_DataServerName) & ";
Initial Catalog=" & Trim(m_DataBaseName) & ";
User Id=" & Trim(m_AdministratorName) & ";
Password=" & Trim(m_PasswordName) & ";"
AdoDatabase.Open scnn
AdoTable.CursorType = adOpenKeyset
AdoTable.LockType = adLockOptimistic
AdoTable.CursorLocation = adUseClient
AdoTable.Open ssql, AdoDatabase, , , adCmdText
If AdoTable.BOF And AdoTable.EOF Then
response = MsgBox("没有符合条件的记录!!",
vbOKOnly + vbInformation, "数据库控件")
AdoTable.Close
Set Adotable=Nothing
AdoDatabase.Close
Set AdoDataBase=Nothing
Exit Sub
End If
ListView1.ColumnHeaders.Clear
ListView1.ListItems.Clear
Dim clmX As ColumnHeader
For I = 0 To AdoTable.Fields.Count - 1
Set clmX = ListView1.ColumnHeaders.Add()
With clmX
.Text = AdoTable.Fields(I).Name
End With
Next
Dim itmX As ListItem
AdoTable.MoveFirst
Do While Not AdoTable.EOF
Set itmX = ListView1.ListItems.Add()
With itmX
If IsNull(AdoTable.Fields(0).Value) Then
.Text = "NULL"
Else
.Text = AdoTable.Fields(0).Value
End If
End With
For I = 1 To AdoTable.Fields.Count - 1
If IsNull(AdoTable.Fields(I).Value) Then
itmX.SubItems(I) = "NULL"
Else
itmX.SubItems(I)
= AdoTable.Fields(I).Value
End If
Next
AdoTable.MoveNext
Loop
ListView1.View = lvwReport
AdoTable.Close
Set Adotable=Nothing
AdoDatabase.Close
Set AdoDataBase=Nothing
Exit Sub
errorhandle:
RaiseEvent Errordatabase
End Sub

当对数据库的操作发生错误后,除了不能正常显示以外,还应通知宿主程序用户。可以通过创建一个叫做Errordatabase的事件实现上述功能。要创建这个事件,把下述代码添加到UserControl对象的GeneralDeclarations段中。

Public Event Errordatabase()

  此事件的工作像其他控件的事件一样。使用控件的用户可以将代码放到这个事件中,用户要做的唯一的事情就是用RaiseEvent方法激发此事件。

(7)编译控件部件(.ocx 文件)。

  现在已经完成了DataListView控件的创建工作,为了在DataLV工程外也可以使用该控件,只需将DataLV工程编译.ocx控件部件即可。

  在【工程组】窗口单击【DataLV】以选择该工程,在【文件】菜单上单击【生成DataLV.ocx】,在【生成工程】对话框中选择控件存放的目录后, 单击【确定】即可创建.ocx 文件。

  一旦生成了.ocx文件的控件,就可以象使用其它控件一样来随心所欲地使用它了。

 4)结束语

  ActiveX技术可以灵活、高效的实现可交互、重入、重用、完全分布式、与语言无关的各种应用。随着ActiveX技术的发展,ActiveX控件在应用程序中的作用将会显得越来越重要,那么创建一个功能完善、具有自己特色的ActiveX控件就非常具有现实意义。只要掌握了创建ActiveX控件的基本方法,就不难创建自定制的可在各种应用领域使用的ActiveX控件。

  但是,ActiveX技术也有一些明显缺点,ActiveX技术依赖于Windows平台,对广泛应用的UNIX平台目前仍不兼容,另外 ActiveX在许多方面的性能还较弱,ActiveX技术仍需要不断完善和发展。

阅读全文
0 0

相关文章推荐

img
取 消
img