Welcome

首页 / 软件开发 / Delphi / 第二十章-开发Delphi对象式数据管理功能(五)(6)

第二十章-开发Delphi对象式数据管理功能(五)(6)2007-05-0720.3.2.4 BLOB字段与Stream对象

因为Delphi中,BLOB字段是通过BLOB流来访问的,所以可以很容易地在BLOB字段和Stream对象之间传递数据。为此,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服务器的数据

对象链接和嵌入(Object Linking and Embedding,简称OLE),是一组服务功能,它提供了一种用来源于不同应用程序的信息创建复合文档的强有力方法。

通过把图像、图形、表格、声音、注解、文件和其它表示手段描述成对象,用它能在不同软件厂家提供的应用程序中更为容易地交换合成和处理数据它是应用程序的集成更为容易。OLE2.0支持直观编辑。用户不需切换到不同窗口就能在文档中直接对对象进行操作,改进了操作环境。用户不用再关注应用程序和操作环境,只需关注于使用对象技术的数据和文件,便能完成全部工作。

OLE已成为操作系统功能上的一大标准,各大软商纷纷在开发工具中支持OLE 2.0规范。Delphi 2.0提供了OleContainer对象支持OLE窗户应用程序的开发。

尽管通过OLE可以用来源于不同应用程序的信息创建复合文档,充分体现以任务、以文档为中心的思想,但是很难分解来自其它应用程序中的嵌入数据,以进行特殊的处理。

例如,一套多媒体电子文档管理系统,系统需要数据库管理功能文档编辑功能,全文检索功能等。在文档编辑功能的实现上,如果能利用中文Word 或写字板之类的强大的编辑排版功能,就可以省却重新开发一个文档编辑的费用,使用具有直观编辑的OLE复合文档嵌入Word的DOC数据或RTF数据当然是最佳的选择。 但问题在于全文检索系统要求能直接在文档中搜索关键字,因此要求将文档数据从OLE嵌入数据或文档中的本地数据中分离出来。

Delphi 2.0的OleContainer部件支持存储OLE对象数据。OLE对象数据包括两部分:OLE类描述信息和OLE服务器嵌入数据。一般说来,OLE服务器嵌入数据是以服务器支持的数据格式存储的; 比方说,中文Word 6.0的嵌入数据的格式就是Word 6.0文档的格式。因此,要将文档数据从OLE 嵌入式文档中分离出来就是要访问第二部分数据。

我们分析了Delphi 2.0的OleContainer对象存取复合文档的程序,得到分离数据的方法。

让我们来看一段OleContainer对象存储数据的程序:

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对象执行了两次往流中写数据的操作。

Stream.WriteBuffer(Header, Size(Header));

Stream.WriteBuffer(Buffer^, Header.DataSize);

前一语句是写入OLE类描述信息,后一句语句是写入OLE服务器的嵌入数据。Header是TStreamHeader记录类型的变量。TStreamHeader记录的定义如下:

TStreamHeader = record

case Integer of

0: ( { 新版OLE对象 }

Signature: Integer;

DrawAspect: Integer;

DataSize: Integer);

1: ( { 旧版OLE对象 }

PartRect: TSmallRect);

end;

因此读OLE服务器嵌入数据时,要跳过文件头的TStreamHeader记录。下面就是如何分离OLE服务器嵌入数据的程序:

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包含的服务器对象是中文Word 6.0,程序中将分离出的数据存储在磁盘文件“TEST.DOC”上。如果希望存储在不同的媒介上,可以使用相应的Stream对象,分离的方法类似。但是,这种方法并非对所有的OLE服务器数据都适用,如Windows 95 附件中的写字板(WordPad)就不行。