用SQL Server為Web瀏覽器提供映像2

來源:互聯網
上載者:User
建立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.Errors
Dim errLoop As ADODB.Error
Dim strError As String
Dim i As Integer
'**********************************************************
'作用:處理可能的錯誤。
'**********************************************************

  If mAdoConn.State = adStateClosed Then GoTo Done
   i = 1
   Set adoErrs = mAdoConn.Errors
  For Each errLoop In adoErrs  '枚舉錯誤集。      
     With errLoop
        strError = strError & vbCrLf & "   ADO Error   #" & .Number
        strError = strError & vbCrLf & "   Description  " & .Description
        strError = strError & vbCrLf & "   Source       " & .Source
        i = i + 1
     End With
  Next

Done:
  Err.Raise vbObjectError + 21, "", strError
End Sub

Private Sub Class_Initialize()
  mlngNumberOfFiles = 0
End Sub

Private Sub Class_Terminate()
Dim i As Integer
On Error GoTo Error_handler
   If mAdoRst.State = adStateOpen Then mAdoRst.Close  '關閉記錄集。      
   If mAdoConn.State = adStateOpen Then mAdoConn.Close  '關閉串連。
      Set mAdoRst = Nothing
      Set mAdoConn = Nothing
Exit Sub

Error_handler:
  Call HandleError
End Sub

Error_handler:
  Call HandleError
End Sub


下一步是編譯動態連結程式庫。在檔案(File)菜單裡,單擊建立(Make) ImageLoader.dll。VB會詢問儲存動態連結程式庫的位
置,然後就編譯項目。在要ASP檔案裡使用ImageLoader.dll這個動態連結程式庫,必須在Windows註冊表裡註冊它。操作方法
是,在NT的啟動菜單裡,選擇運行(Run),然後在輸入框裡輸入下面的命令列:

regsvr32 localpath\ImageLoader
注意,實際使用時要用動態連結程式庫實際所在的完整路徑替換上面命令列裡的“localpath”。現在,就可以在程式裡,比如
ASP檔案裡使用這個動態連結程式庫了。


相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。