全國計算機等級考試二級Delphi輔導(dǎo)講義 223

字號:

20.3.2.3 BLOB字段與文本
    Delphi BLOB字段中增加了大型文本的處理能力。可以在TBlobField和Strings中自由地交換數(shù)據(jù)。
    procedure TBlobField.LoadFromStrings(Strings: TStrings);
    var
    BlobStream: TBlobStream;
    begin
    BlobStream := TBlobStream.Create(Self, bmWrite);
    try
    Strings.SaveToStream(BlobStream);
    finally
    BlobStream.Free;
    end;
    end;
    procedure TBlobField.SaveToStrings(Strings: TStrings);
    var
    BlobStream: TBlobStream;
    begin
    BlobStream := TBlobStream.Create(Self, bmRead);
    try
    Strings.LoadFromStream(BlobStream);
    finally
    BlobStream.Free;
    end;
    end;
    20.3.2.4 BLOB字段與Stream對象
    因為Delphi中,BLOB字段是通過BLOB流來訪問的,所以可以很容易地在BLOB字段和Stream對象之間傳遞數(shù)據(jù)。為此,TBlobField對象提供了LoadFromStream和SaveToStream方法。
    procedure TBlobField.LoadFromStream(Stream: TStream);
    var
    BlobStream: TBlobStream;
    begin
    BlobStream := TBlobStream.Create(Self, bmWrite);
    try
    BlobStream.CopyFrom(Stream, 0);
    finally
    BlobStream.Free;
    end;
    end;
    procedure TBlobField.SaveToStream(Stream: TStream);
    var
    BlobStream: TBlobStream;
    begin
    BlobStream := TBlobStream.Create(Self, bmRead);
    try
    Stream.CopyFrom(BlobStream, 0);
    finally
    BlobStream.Free;
    end;
    end;
    20.3.3 存取嵌入在OleContainer對象中的OLE服務(wù)器的數(shù)據(jù)
    對象鏈接和嵌入(Object Linking and Embedding,簡稱OLE),是一組服務(wù)功能,它提供了一種用來源于不同應(yīng)用程序的信息創(chuàng)建復(fù)合文檔的強有力方法。
    通過把圖像、圖形、表格、聲音、注解、文件和其它表示手段描述成對象,用它能在不同軟件廠家提供的應(yīng)用程序中更為容易地交換合成和處理數(shù)據(jù)它是應(yīng)用程序的集成更為容易。OLE2.0支持直觀編輯。用戶不需切換到不同窗口就能在文檔中直接對對象進(jìn)行操作,改進(jìn)了操作環(huán)境。用戶不用再關(guān)注應(yīng)用程序和操作環(huán)境,只需關(guān)注于使用對象技術(shù)的數(shù)據(jù)和文件,便能完成全部工作。
    OLE已成為操作系統(tǒng)功能上的一大標(biāo)準(zhǔn),各大軟商紛紛在開發(fā)工具中支持OLE 2.0規(guī)范。Delphi 2.0提供了OleContainer對象支持OLE窗戶應(yīng)用程序的開發(fā)。
    盡管通過OLE可以用來源于不同應(yīng)用程序的信息創(chuàng)建復(fù)合文檔,充分體現(xiàn)以任務(wù)、以文檔為中心的思想,但是很難分解來自其它應(yīng)用程序中的嵌入數(shù)據(jù),以進(jìn)行特殊的處理。
    例如,一套多媒體電子文檔管理系統(tǒng),系統(tǒng)需要數(shù)據(jù)庫管理功能文檔編輯功能,全文檢索功能等。在文檔編輯功能的實現(xiàn)上,如果能利用中文Word 或?qū)懽职逯惖膹姶蟮木庉嬇虐婀δ?,就可以省卻重新開發(fā)一個文檔編輯的費用,使用具有直觀編輯的OLE復(fù)合文檔嵌入Word的DOC數(shù)據(jù)或RTF數(shù)據(jù)當(dāng)然是的選擇。 但問題在于全文檢索系統(tǒng)要求能直接在文檔中搜索關(guān)鍵字,因此要求將文檔數(shù)據(jù)從OLE嵌入數(shù)據(jù)或文檔中的本地數(shù)據(jù)中分離出來。
    Delphi 2.0的OleContainer部件支持存儲OLE對象數(shù)據(jù)。OLE對象數(shù)據(jù)包括兩部分:OLE類描述信息和OLE服務(wù)器嵌入數(shù)據(jù)。一般說來,OLE服務(wù)器嵌入數(shù)據(jù)是以服務(wù)器支持的數(shù)據(jù)格式存儲的; 比方說,中文Word 6.0的嵌入數(shù)據(jù)的格式就是Word 6.0文檔的格式。因此,要將文檔數(shù)據(jù)從OLE 嵌入式文檔中分離出來就是要訪問第二部分?jǐn)?shù)據(jù)。
    我們分析了Delphi 2.0的OleContainer對象存取復(fù)合文檔的程序,得到分離數(shù)據(jù)的方法。
    讓我們來看一段OleContainer對象存儲數(shù)據(jù)的程序:
    procedure TOleContainer.SaveToStream(Stream: TStream);
    var
    DataHandle: HGlobal;
    Buffer: Pointer;
    Header: TStreamHeader;
    R: TRect;
    ……
    begin
    ……
    try
    ……
    if FOldStreamFormat then
    begin
    R := BoundsRect;
    Header.PartRect.Left := R.Left;
    Header.PartRect.Top := R.Top;
    Header.PartRect.Right := R.Right;
    Header.PartRect.Bottom := R.Bottom;
    end else
    begin
    Header.Signature := StreamSignature;
    Header.DrawAspect := FDrawAspect;
    end;
    Header.DataSize := GlobalSize(DataHandle);
    Stream.WriteBuffer(Header, SizeOf(Header));
    Buffer := GlobalLock(DataHandle);
    try
    Stream.WriteBuffer(Buffer^, Header.DataSize);
    finally
    GlobalUnlock(DataHandle);
    end;
    finally
    ReleaseObject(TempStorage);
    ReleaseObject(TempLockBytes);
    end;
    end;
    程序中,OleContainer對象執(zhí)行了兩次往流中寫數(shù)據(jù)的操作。
    Stream.WriteBuffer(Header, Size(Header));
    Stream.WriteBuffer(Buffer^, Header.DataSize);
    前一語句是寫入OLE類描述信息,后一句語句是寫入OLE服務(wù)器的嵌入數(shù)據(jù)。Header是TStreamHeader記錄類型的變量。TStreamHeader記錄的定義如下:
    TStreamHeader = record
    case Integer of
    0: ( { 新版OLE對象 }
    Signature: Integer;
    DrawAspect: Integer;
    DataSize: Integer);
    1: ( { 舊版OLE對象 }
    PartRect: TSmallRect);
    end;
    因此讀OLE服務(wù)器嵌入數(shù)據(jù)時,要跳過文件頭的TStreamHeader記錄。下面就是如何分離OLE服務(wù)器嵌入數(shù)據(jù)的程序:
    var
    Stream : TMemoryStream;
    FileStream : TFileStream;
    begin
    Stream := TMemoryStream.Create;
    FileStream := TFileStream.Create('TEST.DOC', fmCreate) ;
    with OleContainer1 do
    if (State <> osEmpty) then
    SaveToStream(Stream);
    Stream.Seek(Sizeof(TStreamHeader), 0);
    FileStream.CopyFrom(Stream, Stream.Size - SizeOf(TStreamHeader));
    Stream.Free;
    FileStream.Free;
    end;
    OleContainer1包含的服務(wù)器對象是中文Word 6.0,程序中將分離出的數(shù)據(jù)存儲在磁盤文件“TEST.DOC”上。如果希望存儲在不同的媒介上,可以使用相應(yīng)的Stream對象,分離的方法類似。但是,這種方法并非對所有的OLE服務(wù)器數(shù)據(jù)都適用,如Windows 95 附件中的寫字板(WordPad)就不行。