您现在的位置: 军旅同心 >> 读书赏析 >> 学习园地 >> 电脑网络 >> 技术文章 >> 文章正文
用SQL Server为Web浏览器提供图像2
作者:采集员 文章来源:来源于网络 点击数: 更新时间:2005-9-10 14:19:47
建立ActiveX 动态链接库

    使用 VB 5.0,我们要开发一个ActiveX 动态链接库。这个动态链接库让我们能够连接到SQL数据库,提取图片数据,
并把它们保存成文件,放在目录里。要建立动态链接库,请在打开VB程序之后执行下列步骤:首先:在文件(File)菜单
里,选择新建项目(New Project)。接着,在新建立项目对话框里,双击ActiveX DLL 图标。VB自动地向项目里增加一个
类,叫做Class1。然后,在属性容器里,双击名称(Name)属性,把它改成clsImageLoader,保持instancing 属性为缺省
值MultiUse不动。最后,在项目(Project)菜单里,选择Project1 属性,打开项目属性对话框。选择通用(General)选
项卡,把项目名称改为ImageLoader。其它字段可以不管,保持原样。单击确定(OK)完成对ImageLoader 这个工程的设
置。

    在类里,写入了5个Let属性,1个Get属性(只读)和两个方法。Let属性传递动态链接库需要的信息,Get属性提供动
态链接库生成的图片文件的位置。两个方法用来打开到数据库的连接,以生成图片文件。表 A 总结了这些属性和方法的作
用。当然,根据项目的需要,可以在类里加入更复杂的功能。

表A: 在ActiveX动态链接库里的属性和方法

属性/方法                                            作用

DbName                                  打开数据库连接所需的数据库名称。

TableName,
NameOfImageColumn,                      打开记录集所需要的信息。
NameOfImageTypeColumn,
NameOfImageIdColumn

ImageFile (只读)                      把图片文件的名称和位置返回给容器。

OpenConnection (方法)                         打开数据库连接。

CreateTemplateImageFile (方法)              从数据库提取图片数据,并把它保存到目录里。


    在类里还有其它的私有子程序,用来初始化类、终止类、打开记录集、建立图片文件,以及处理可能的错误。

注意微软活动数据对象ADO1.5(现在为2.0)被用来连接SQL数据库。也可以使用其它数据访问方法,比如远程数据对象RDO。
在这个项目里,必须使用ADO。操作方法是,单击项目(Project)菜单,然后选择引用(References)菜单 项。在引用对
话框里,选中微软ActiveX Data Objects 1.5 库,然后单击确定(OK)。

在列表 B里,列出了类ImageLoader 完整源代码。类里使用的变量定义都在代码内部给出,还有其它注释,帮助理解上下
文。

列表 B:类 ImageLoader 的完整源代码

Private mAdoConn As New ADODB.Connection
Private mAdoRst As New ADODB.Recordset
Private mstrDbName As String
Private mstrTableName As String
Private mstrImageColumnName As String '图片字的名称。
Private mstrImageTypeColumnName As String '图片类型字段的名称。
Private mstrImageIdColumnName As String '图片ID字段的名称。
Private mstrFileName() As String '数组,里面包含文件名和路径。
Private mlngImageId() As Long '数组,里面包含图片ID
Private mlngNumberOfFiles As Long
Const BLOCKSIZE = 102400


Public Property Let DbName(ByVal strVal As String)
  mstrDbName = strVal
End Property

Public Property Let TableName(ByVal strVal As String)
  mstrTableName = strVal
End Property

Public Property Let NameOfImageColumn(ByVal strVal As String)
  mstrImageColumnName = strVal
End Property

Public Property Let NameOfImageTypeColumn(ByVal strVal As String)
  mstrImageTypeColumnName = strVal
End Property

Public Property Let NameOfImageIdColumn(ByVal strVal As String)
  mstrImageIdColumnName = strVal
End Property

Public Property Get ImageFile(ByVal ImageId As Integer) As String
  Dim intPos As Integer
  Dim blnFindId As Boolean
  Dim i As Integer

  blnFindId = False
  For i = 0 To mlngNumberOfFiles - 1
     If mlngImageId(i) = ImageId Then
        intPos = 5 + Len(ImageId) + 3
        ImageFile = Right(mstrFileName(i), intPos) 'reformat the location of file.
        blnFindId = True
     End If
  Next i

  If blnFindId = False Then
     Err.Clear
     Err.Raise vbObjectError + 23, "Get ImageFile", "Can't find image file!"
  End If

End Property


Public Sub OpenConnection()
'**********************************************************
'作用:打开数据库连接。
'**********************************************************

On Error GoTo Error_handler
  If mstrDbName = "" Then GoTo Error_handler
  If mAdoConn.State = adStateOpen Then mAdoConn.Close
  mAdoConn.ConnectionString = "DRIVER={SQL Server};SERVER=(local);UID=sa;PWD=;WSID=JIA;DATABASE=" &
mstrDbName
  mAdoConn.ConnectionTimeout = 15
  mAdoConn.Open
Exit Sub

Error_handler:
  Call HandleError
End Sub

Public Sub CreateTempImageFile(ByVal ImageId As Integer)
  Dim strImageType As String
  Dim i As Integer
'**********************************************************
'作用:打开记录集,提取二进制数据,并把数据存入文件。注意文件名使用图片ID生成。
'输入:图片ID。
'**********************************************************
If mAdoConn.State = adStateClosed Then Exit Sub

  Call OpenRecordset(ImageId)

  If mAdoRst.State = adStateClosed Then Exit Sub

On Error GoTo Error_handler

  For i = 0 To mlngNumberOfFiles - 1
     '检测图片文件是否已经存在。
     If mlngImageId(i) = ImageId Then Exit Sub
  Next i

  mlngNumberOfFiles = mlngNumberOfFiles + 1
  ReDim Preserve mstrFileName(mlngNumberOfFiles) '改变数组大小。
  ReDim Preserve mlngImageId(mlngNumberOfFiles) '改变数组大小。
  mlngImageId(mlngNumberOfFiles - 1) = ImageId
  strImageType = mAdoRst.Fields(mstrImageTypeColumnName) ' 取得图片类型。   
  mstrFileName(mlngNumberOfFiles - 1) = App.Path & "images" & _
    "image" & LTrim(Str(ImageId)) & "." & strImageType  '取得图片文件名称和位置。
  Call ReadFromDB(mAdoRst.Fields(mstrImageColumnName), _
     mstrFileName(mlngNumberOfFiles - 1), AdoRst.Fields(mstrImageColumnName).ActualSize)
  Exit Sub

Error_handler:
  Call HandleError

End Sub

Private Sub OpenRecordset(ByVal ImageId As Integer)
Dim SqlText As String
'**********************************************************
'作用:打开记录集。
'输入:图片ID。
'**********************************************************

On Error GoTo Error_handler
  If mAdoRst.State = adStateOpen Then mAdoRst.Close
  SqlText = "SELECT " & mstrImageColumnName & "," & _
     mstrImageTypeColumnName & " FROM " & mstrTableName & _
     " WHERE " & mstrImageIdColumnName & "=" & ImageId

  Set mAdoRst.ActiveConnection = mAdoConn
  mAdoRst.Open SqlText, , adOpenStatic, adLockReadOnly 'Open recordset.

Exit Sub


Error_handler:
  Call HandleError
End Sub

Private Sub ReadFromDB(fld As ADODB.Field, ByVal DiskFile As String, _
                    FldSize As Long)
Dim NumBlocks As Integer
Dim LeftOver As Long
Dim byteData() As Byte   '字节数组,用于长的可变二进制数据LongVarBinary。
Dim strData As String    '字符串,用于长的可变二进制数据LongVarChar。
Dim DestFileNum As Integer
Dim pic As Variant
Dim i As Integer
'**********************************************************
'作用:提取二进制数据并把数据放入文件。
'输入:图片字段,文件名/位置和数据尺寸。
'**********************************************************

  If Len(Dir(DiskFile)) > 0 Then '删除已经存在的目标文件。
     Kill DiskFile
  End If

  DestFileNum = FreeFile
  Open DiskFile For Binary As DestFileNum
  NumBlocks = FldSize BLOCKSIZE
  LeftOver = FldSize Mod BLOCKSIZE

  Select Case fld.Type
  Case adLongVarBinary '用于图片数据类型。
     byteData() = fld.GetChunk(LeftOver)
     pic = fld.GetChunk(LeftOver)
     Put DestFileNum, , byteData()

     For i = 1 To NumBlocks
        byteData() = fld.GetChunk(BLOCKSIZE)
        Put DestFileNum, , byteData()
     Next i

  Case adLongVarChar '用于文本数据类型。
     For i = 1 To NumBlocks
        strData = String(BLOCKSIZE, 32)
        strData = fld.GetChunk(BLOCKSIZE)
        Put DestFileNum, , strData
     Next i

     strData = String(LeftOver, 32)
     strData = fld.GetChunk(LeftOver)
        Put DestFileNum, , strData
     Case Else
        Err.Clear
        Err.Raise vbObjectError + 22, "Read from DB", "Not a Chunk Required column!"
  End Select

  Close DestFileNum

End Sub

Private Sub HandleError()
Dim adoErrs As ADODB.Er

[1] [2] 下一页


 
免责声明:作品版权归所属媒体与作者所有!!本站刊载此文不代表同意其说法或描述,仅为提供更多信息。如果您认为我们侵犯了您的版权,请告知!本站立即删除。有异议请联系我们。
文章录入:烟灰缸    责任编辑:烟灰缸 
网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
| 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 |