📄 055.htm
字号:
<p>Size: Longint;</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">Header: TGraphicHeader;</font><font face="宋体"
lang="ZH-CN"></p>
<p></font><font face="Arial">begin</p>
<p>BlobStream := TBlobStream.Create(Self, bmRead);</p>
<p>try</p>
<p>Size := BlobStream.Size;</p>
<p>if Size >= SizeOf(TGraphicHeader) then</p>
<p>begin</p>
<p>BlobStream.Read(Header, SizeOf(Header));</p>
<p>if (Header.Count <> 1) or (Header.HType <> $0100) or</p>
<p>(Header.Size <> Size - SizeOf(Header)) then</p>
<p>BlobStream.Position := 0;</p>
<p>end;</p>
<p>Bitmap.LoadFromStream(BlobStream);</p>
<p>finally</p>
<p>BlobStream.Free;</p>
<p>end;</p>
<p>end;</p>
<p> </p>
<p></font><font face="宋体" lang="ZH-CN">程序中按两种方式存取数据,对于位图数据,数据的起点是流的</font><font
face="Arial">Potition</font><font face="宋体" lang="ZH-CN">为</font><font face="Arial">0</font><font
face="宋体" lang="ZH-CN">处,对于图形或其它类型的</font><font face="Arial">Blob</font><font
face="宋体" lang="ZH-CN">数据,则以流的</font><font face="Arial">Position</font><font
face="宋体" lang="ZH-CN">为</font><font face="Arial">SizeOf(Header) + 1</font><font
face="宋体" lang="ZH-CN">处开始,</font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN">即多了个头信息。</p>
<p> </font><font face="Arial"></p>
<p>20.3.2.3 BLOB</font><font face="宋体" lang="ZH-CN">字段与文本</p>
<p> </p>
<p> </font><font face="Arial">Delphi BLOB</font><font face="宋体" lang="ZH-CN">字段中增加了大型文本的处理能力。可以在</font><font
face="Arial">TBlobField</font><font face="宋体" lang="ZH-CN">和</font><font
face="Arial">Strings</font><font face="宋体" lang="ZH-CN">中自由地交换数据。</p>
<p> </p>
<p></font><font face="Arial">procedure TBlobField.LoadFromStrings(Strings: TStrings);</p>
<p>var</p>
<p>BlobStream: TBlobStream;</p>
<p>begin</p>
<p>BlobStream := TBlobStream.Create(Self, bmWrite);</p>
<p>try</p>
<p>Strings.SaveToStream(BlobStream);</p>
<p>finally</p>
<p>BlobStream.Free;</p>
<p>end;</p>
<p>end;</p>
<p> </p>
<p>procedure TBlobField.SaveToStrings(Strings: TStrings);</p>
<p>var</p>
<p>BlobStream: TBlobStream;</p>
<p>begin</p>
<p>BlobStream := TBlobStream.Create(Self, bmRead);</p>
<p>try</p>
<p>Strings.LoadFromStream(BlobStream);</p>
<p>finally</p>
<p>BlobStream.Free;</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">end;</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">end;</p>
<p> </p>
<p>20.3.2.4 BLOB</font><font face="宋体" lang="ZH-CN">字段与</font><font face="Arial">Stream</font><font
face="宋体" lang="ZH-CN">对象</p>
<p> </p>
<p> 因为</font><font face="Arial">Delphi</font><font face="宋体" lang="ZH-CN">中,</font><font
face="Arial">BLOB</font><font face="宋体" lang="ZH-CN">字段是通过</font><font
face="Arial">BLOB</font><font face="宋体" lang="ZH-CN">流来访问的,所以可以很容易地在</font><font
face="Arial">BLOB</font><font face="宋体" lang="ZH-CN">字段和</font><font
face="Arial">Stream</font><font face="宋体" lang="ZH-CN">对象之间传递数据。为此,</font><font
face="Arial">TBlobField</font><font face="宋体" lang="ZH-CN">对象提供了</font><font
face="Arial">LoadFromStream</font><font face="宋体" lang="ZH-CN">和</font><font
face="Arial">SaveToStream</font><font face="宋体" lang="ZH-CN">方法。</p>
<p> </p>
<p></font><font face="Arial">procedure TBlobField.LoadFromStream(Stream: TStream);</p>
<p>var</p>
<p>BlobStream: TBlobStream;</p>
<p>begin</p>
<p>BlobStream := TBlobStream.Create(Self, bmWrite);</p>
<p>try</p>
<p>BlobStream.CopyFrom(Stream, 0);</p>
<p>finally</p>
<p>BlobStream.Free;</p>
<p>end;</p>
<p>end;</p>
<p> </p>
<p>procedure TBlobField.SaveToStream(Stream: TStream);</p>
<p>var</p>
<p>BlobStream: TBlobStream;</p>
<p>begin</p>
<p>BlobStream := TBlobStream.Create(Self, bmRead);</p>
<p>try</p>
<p>Stream.CopyFrom(BlobStream, 0);</p>
<p>finally</p>
<p>BlobStream.Free;</p>
<p>end;</p>
<p>end;</p>
<p> </p>
<p>20.3.3 </font><font face="宋体" lang="ZH-CN">存取嵌入在</font><font face="Arial">OleContainer</font><font
face="宋体" lang="ZH-CN">对象中的</font><font face="Arial">OLE</font><font
face="宋体" lang="ZH-CN">服务器的数据</p>
<p> </p>
<p> 对象链接和嵌入</font><font face="Arial">(Object Linking and Embedding</font><font
face="宋体" lang="ZH-CN">,简称</font><font face="Arial">OLE)</font><font
face="宋体" lang="ZH-CN">,是一组服务功能,它提供了一种用来源于不同应用程序的信息创建复合文档的强有力方法。</p>
<p> 通过把图像、图形、表格、声音、注解、文件和其它表示手段描述成对象,用它能在不同软件厂家提供的应用程序中更为容易地交换合成和处理数据它是应用程序的集成更为容易。</font><font
face="Arial">OLE2.0</font><font face="宋体" lang="ZH-CN">支持直观编辑。用户不需切换到不同窗口就能在文档中直接对对象进行操作,改进了操作环境。用户不用再关注应用程序和操作环境,只需关注于使用对象技术的数据和文件,便能完成全部工作。</p>
<p> </font><font face="Arial">OLE</font><font face="宋体" lang="ZH-CN">已成为操作系统功能上的一大标准,各大软商纷纷在开发工具中支持</font><font
face="Arial">OLE 2.0</font><font face="宋体" lang="ZH-CN">规范。</font><font
face="Arial">Delphi 2.0</font><font face="宋体" lang="ZH-CN">提供了</font><font
face="Arial">OleContainer</font><font face="宋体" lang="ZH-CN">对象支持</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">窗户应用程序的开发。</p>
<p> 尽管通过</font><font face="Arial">OLE</font><font face="宋体" lang="ZH-CN">可以用来源于不同应用程序的信息创建复合文档,充分体现以任务、以文档为中心的思想,但是很难分解来自其它应用程序中的嵌入数据,以进行特殊的处理。</p>
<p> 例如,一套多媒体电子文档管理系统,系统需要数据库管理功能文档编辑功能,全文检索功能等。在文档编辑功能的实现上,如果能利用中文</font><font
face="Arial">Word </font><font face="宋体" lang="ZH-CN">或写字板之类的强大的编辑排版功能,就可以省却重新开发一个文档编辑的费用,使用具有直观编辑的</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">复合文档嵌入</font><font
face="Arial">Word</font><font face="宋体" lang="ZH-CN">的</font><font face="Arial">DOC</font><font
face="宋体" lang="ZH-CN">数据或</font><font face="Arial">RTF</font><font
face="宋体" lang="ZH-CN">数据当然是最佳的选择。</font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN">但问题在于全文检索系统要求能直接在文档中搜索关键字,因此要求将文档数据从</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">嵌入数据或文档中的本地数据中分离出来。</p>
<p> </font><font face="Arial">Delphi 2.0</font><font face="宋体" lang="ZH-CN">的</font><font
face="Arial">OleContainer</font><font face="宋体" lang="ZH-CN">部件支持存储</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">对象数据。</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">对象数据包括两部分:</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">类描述信息和</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">服务器嵌入数据。一般说来,</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">服务器嵌入数据是以服务器支持的数据格式存储的</font><font
face="Arial">; </font><font face="宋体" lang="ZH-CN">比方说,中文</font><font
face="Arial">Word 6.0</font><font face="宋体" lang="ZH-CN">的嵌入数据的格式就是</font><font
face="Arial">Word 6.0</font><font face="宋体" lang="ZH-CN">文档的格式。因此,要将文档数据从</font><font
face="Arial">OLE </font><font face="宋体" lang="ZH-CN">嵌入式文档中分离出来就是要访问第二部分数据。</font><font
face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN">我们分析了</font><font face="Arial">Delphi
2.0</font><font face="宋体" lang="ZH-CN">的</font><font face="Arial">OleContainer</font><font
face="宋体" lang="ZH-CN">对象存取复合文档的程序,得到分离数据的方法。</p>
<p> 让我们来看一段</font><font face="Arial">OleContainer</font><font
face="宋体" lang="ZH-CN">对象存储数据的程序:</p>
<p> </p>
<p></font><font face="Arial">procedure TOleContainer.SaveToStream(Stream: TStream);</p>
<p>var</p>
<p>DataHandle: HGlobal;</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">Buffer: Pointer;</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">Header: TStreamHeader;</p>
<p>R: TRect;</p>
<p></font><font face="宋体" lang="ZH-CN"> ……</p>
<p></font><font face="Arial">begin</p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> ……</p>
<p></font><font face="Arial">try</p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> ……</p>
<p></font><font face="Arial">if FOldStreamFormat then</p>
<p>begin</p>
<p>R := BoundsRect;</p>
<p>Header.PartRect.Left := R.Left;</p>
<p>Header.PartRect.Top := R.Top;</p>
<p>Header.PartRect.Right := R.Right;</p>
<p>Header.PartRect.Bottom := R.Bottom;</p>
<p>end else</p>
<p>begin</p>
<p>Header.Signature := StreamSignature;</p>
<p>Header.DrawAspect := FDrawAspect;</p>
<p>end;</p>
<p>Header.DataSize := GlobalSize(DataHandle);</p>
<p>Stream.WriteBuffer(Header, SizeOf(Header));</p>
<p>Buffer := GlobalLock(DataHandle);</p>
<p>try</p>
<p>Stream.WriteBuffer(Buffer^, Header.DataSize);</p>
<p>finally</p>
<p>GlobalUnlock(DataHandle);</p>
<p>end;</p>
<p>finally</p>
<p>ReleaseObject(TempStorage);</p>
<p>ReleaseObject(TempLockBytes);</p>
<p>end;</p>
<p>end;</p>
<p> </p>
<p></font><font face="宋体" lang="ZH-CN">程序中,</font><font face="Arial">OleContainer</font><font
face="宋体" lang="ZH-CN">对象执行了两次往流中写数据的操作。</font><font
face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> </font><font face="Arial">Stream.WriteBuffer(Header,
Size(Header)); </p>
<p>Stream.WriteBuffer(Buffer^, Header.DataSize); </p>
<p> </p>
<p></font><font face="宋体" lang="ZH-CN">前一语句是写入</font><font face="Arial">OLE</font><font
face="宋体" lang="ZH-CN">类描述信息,后一句语句是写入</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">服务器的嵌入数据。</font><font
face="Arial">Header</font><font face="宋体" lang="ZH-CN">是</font><font face="Arial">TStreamHeader</font><font
face="宋体" lang="ZH-CN">记录类型的变量。</font><font face="Arial">TStreamHeader</font><font
face="宋体" lang="ZH-CN">记录的定义如下:</p>
<p> </font><font face="Arial"></p>
<p>TStreamHeader = record</p>
<p>case Integer of</p>
<p>0: ( { </font><font face="宋体" lang="ZH-CN">新版</font><font face="Arial">OLE</font><font
face="宋体" lang="ZH-CN">对象</font><font face="Arial"> }</p>
<p>Signature: Integer; </p>
<p>DrawAspect: Integer; </p>
<p>DataSize: Integer); </p>
<p>1: ( { </font><font face="宋体" lang="ZH-CN">旧版</font><font face="Arial">OLE</font><font
face="宋体" lang="ZH-CN">对象</font><font face="Arial"> }</p>
<p>PartRect: TSmallRect); </p>
<p>end; </p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p> 因此读</font><font face="Arial">OLE</font><font face="宋体" lang="ZH-CN">服务器嵌入数据时,要跳过文件头的</font><font
face="Arial">TStreamHeader</font><font face="宋体" lang="ZH-CN">记录。下面就是如何分离</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">服务器嵌入数据的程序:</p>
<p> </p>
<p></font><font face="Arial">var</p>
<p>Stream : TMemoryStream;</p>
<p>FileStream : TFileStream;</p>
<p>begin</p>
<p>Stream := TMemoryStream.Create;</p>
<p>FileStream := TFileStream.Create('TEST.DOC', fmCreate) ;</p>
<p>with OleContainer1 do</p>
<p>if (State <> osEmpty) then</p>
<p>SaveToStream(Stream);</p>
<p>Stream.Seek(Sizeof(TStreamHeader), 0);</p>
<p>FileStream.CopyFrom(Stream, Stream.Size - SizeOf(TStreamHeader));</p>
<p>Stream.Free;</p>
<p>FileStream.Free;</p>
<p>end; </p>
<p> </p>
<p>OleContainer1</font><font face="宋体" lang="ZH-CN">包含的服务器对象是中文</font><font
face="Arial">Word 6.0</font><font face="宋体" lang="ZH-CN">,程序中将分离出的数据存储在磁盘文件“</font><font
fac
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -