📄 055.htm
字号:
<p> </p>
<p></font><font face="Arial">procedure TScriptForm.ScriptToCard;</p>
<p>var</p>
<p>In, Out: TStream;</p>
<p>begin</p>
<p>In := TMemoryStream.Create;</p>
<p>Out := TMemoryStream.Create;</p>
<p>try</p>
<p>ScriptForm.ScriptEdit.Lines.SaveToFromStream(In);</p>
<p>ObjectTextToResource(In, out);</p>
<p>In.ReadComponentRes(DesignWin);</p>
<p>finally</p>
<p>In.Free;</p>
<p>Out.Free;</p>
<p>end;</p>
<p>end;</p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p> 这两段程序是对整个卡片,即窗体级,进行转换的。</font><font
face="Arial">ObjectBinaryToText</font><font face="宋体" lang="ZH-CN">和</font><font
face="Arial">ObjectTextToBinary</font><font face="宋体" lang="ZH-CN">过程可以细化到部件级的转换。因此超媒体脚本语言的编辑可以细化到媒体对象级。</p>
<p> </font><font face="Arial">4. </font><font face="宋体" lang="ZH-CN">超媒体编辑和表现系统与动态</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件的扩展</p>
<p> 超媒体系统的媒体编辑与卡片管理有其特殊的需求,比如链接需求。这时采用已有的窗体部件和媒体部件并按常规的</font><font
face="Arial">DFM</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"> </font><font face="宋体"
lang="ZH-CN">利用</font><font face="Arial">Delphi</font><font face="宋体" lang="ZH-CN">部件开发技术,继承和开发新的部件增加新的超媒体特有的属性和处理方法</p>
<p> ●</font><font face="Arial"> </font><font face="宋体" lang="ZH-CN">扩展</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件结构,使之能按自己的需要任意地存取和转换部件和</font><font
face="Arial">DFM</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">DFM</font><font face="宋体" lang="ZH-CN">文件相同。而后者需要</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">的存取和转换上作比较大的改动。下文介绍扩展</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件的思路。</p>
<p> 扩展动态</font><font face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件的总体思路是降低处理操作的数据的颗粒度,即从原先窗体级降低到部件级。</p>
<p> 下面是存取操作的扩展示范:</p>
<p> </p>
<p> </font><font face="Arial">var</p>
<p>FileStream: TStream; </p>
<p>I: Integer;</p>
<p>begin</p>
<p>FileStream := TFileStream.Create('OverView.Crd', fmOpenWrite); </p>
<p>With TWriter.Create(FileStream, 4096) do</p>
<p>try</p>
<p>for I := 0 to DesignWin.ControlCount - 1 do</p>
<p>begin</p>
<p>WriteInteger(MMID[i]); </p>
<p>WriteRootComponent(DesignWin.Controls[i]); </p>
<p>{ </font><font face="宋体" lang="ZH-CN">写相应媒体扩展信息</font><font
face="Arial"> }</p>
<p></font><font face="宋体" lang="ZH-CN"> ……</p>
<p> </font><font face="Arial"> end; </p>
<p>WriteListEnd; </p>
<p>finally.</p>
<p>Free; </p>
<p>end; </p>
<p>FileStream.Free; </p>
<p>end; </p>
<p> </p>
<p>WriteInteger(MMID[i])</font><font face="宋体" lang="ZH-CN">语句是写入媒体标识。</p>
<p> 下面是相应的读扩展</font><font face="Arial">DFM</font><font
face="宋体" lang="ZH-CN">的程序:</p>
<p> </p>
<p> </font><font face="Arial">var</p>
<p>PropInfo: PPropInfo;</p>
<p>Method : TMethod;</p>
<p>FileStream: TStream; </p>
<p>I: Integer;</p>
<p>begin</p>
<p>FileStream := TFileStream.Create('OverView.Crd', fmOpenRead); </p>
<p>With TReader.Create(FileStream, 4096) do</p>
<p>try</p>
<p>while not EndOfList do</p>
<p>begin</p>
<p>case ReadInteger of</p>
<p>IDText: begin</p>
<p>Ctrl := TControl(ReadRootComponent(nil));</p>
<p>PropInfo := GetPropInfo(Ctrl.ClassInfo, 'OnClick');</p>
<p>Method.Code:= Self.MethodAddress(MethodName);</p>
<p>Method.Data := Self;</p>
<p>if Method.Code <> nil then</p>
<p>SetMethodProp(Ctrl, PropInfo, Method);</p>
<p>DesignWin.InsertControl(Ctrl);</p>
<p>end;</p>
<p>IDImage:</p>
<p></font><font face="宋体" lang="ZH-CN"> ……</font><font face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> end; </p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> ……</font><font face="Arial"></p>
<p>WriteListEnd; </p>
<p>end;</p>
<p>finally.</p>
<p>Free; </p>
<p>end; </p>
<p>FileStream.Free; </p>
<p>end; </p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p> </font><font face="Arial">SetMethodProp</font><font face="宋体" lang="ZH-CN">过程是用于重新联接控制和它的事件处理过程。类似的功能还可以用</font><font
face="Arial">TReader</font><font face="宋体" lang="ZH-CN">对象的</font><font
face="Arial">OnFindMethod</font><font face="宋体" lang="ZH-CN">事件的处理过程来实现。</p>
<p> 实现脚本语言扩展的基本方法与存取扩展类似,但它还要加扩展媒体信息转换为文本,并插入到部件的脚本描述中。</p>
<p> </font><font face="Arial"></p>
<p>20.3.2 </font><font face="宋体" lang="ZH-CN">数据库</font><font face="Arial">BLOB</font><font
face="宋体" lang="ZH-CN">字段应用</p>
<p> </p>
<p> </font><font face="Arial">Delphi VCL</font><font face="宋体" lang="ZH-CN">提供了</font><font
face="Arial">TBlobStream</font><font face="宋体" lang="ZH-CN">对象支持对数据库</font><font
face="Arial">BLOB</font><font face="宋体" lang="ZH-CN">字段的存取。</font><font
face="Arial">Delphi </font><font face="宋体" lang="ZH-CN">的</font><font face="Arial">TBlobStream</font><font
face="宋体" lang="ZH-CN">对象的作用在于一方面可以使</font><font
face="Arial">Delphi</font><font face="宋体" lang="ZH-CN">应用程序充分利用多媒体数据库的数据管理能力。另一方面又能利用</font><font
face="Arial">Delphi Object Pascal</font><font face="宋体" lang="ZH-CN">的程序设计能力给关系型多媒体数据库提供底层控制能力和全方位的功能扩展余地。</p>
<p> </font><font face="Arial"></p>
<p>20.3.2.1 TBlobStream</font><font face="宋体" lang="ZH-CN">的使用</p>
<p> </p>
<p> </font><font face="Arial">TBlobStream</font><font face="宋体" lang="ZH-CN">对象用一个</font><font
face="Arial">TBlobField</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">字段中存取数据。</p>
<p> </p>
<p> </font><font face="Arial">var</p>
<p>BlobStream: TBlobStream; </p>
<p>I: Integer;</p>
<p>begin</p>
<p>BlobStream := TBlobStream.Create(TBlobField(CardTable.Fields[10], bmWrite);</p>
<p>With TWriter.Create(BlobStream, 4096) do</p>
<p>try</p>
<p>for I := 0 to DesignWin.ControlCount - 1 do</p>
<p>begin</p>
<p>WriteInteger(MMID[i]); </p>
<p>WriteRootComponent(DesignWin.Controls[i]); </p>
<p>{ </font><font face="宋体" lang="ZH-CN">写相应媒体扩展信息</font><font
face="Arial"> }</p>
<p></font><font face="宋体" lang="ZH-CN"> ……</p>
<p> </font><font face="Arial"> end; </p>
<p>WriteListEnd; </p>
<p>finally.</p>
<p>Free; </p>
<p>end; </p>
<p>BlobStream.Free; </p>
<p>CardTable.Post;</p>
<p>end; </p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p> </font><font face="Arial">Fields</font><font face="宋体" lang="ZH-CN">变量是表示数据库记录的字段数组,</font><font
face="Arial">Fields[10]</font><font face="宋体" lang="ZH-CN">正是数据库的</font><font
face="Arial">BLOB </font><font face="宋体" lang="ZH-CN">字段。</font><font
face="Arial">CardTable</font><font face="宋体" lang="ZH-CN">的</font><font face="Arial">Post</font><font
face="宋体" lang="ZH-CN">方法将数据库的修改反馈到数据库的物理存储上。</p>
<p> 上面这段程序是超媒体卡片存储的部分源程序,我们就是将卡片保存在数据库</font><font
face="Arial">BLOB</font><font face="宋体" lang="ZH-CN">字段中,实现将超文本和关系数据库两种数据管理方式结合起来。读卡片的程序如下:</p>
<p> </p>
<p> </font><font face="Arial">var</p>
<p>PropInfo: PPropInfo;</p>
<p>Method: TMethod;</p>
<p>Blobtream: TStream; </p>
<p>I: Integer;</p>
<p>begin</p>
<p>BlobStream := TBlobStream.Create(TBlobField(CardTable.Fields[10]), bmRead); </p>
<p>With TReader.Create(BlobStream, 4096) do</p>
<p>try</p>
<p>while not EndOfList do</p>
<p>begin</p>
<p>case ReadInteger of</p>
<p>IDText: begin</p>
<p>Ctrl := TControl(ReadRootComponent(nil));</p>
<p>PropInfo := GetPropInfo(Ctrl.ClassInfo, 'OnClick');</p>
<p>Method.Code:= Self.MethodAddress(MethodName);</p>
<p>Method.Data := Self;</p>
<p>if Method.Code <> nil then</p>
<p>SetMethodProp(Ctrl, PropInfo, Method);</p>
<p>DesignWin.InsertControl(Ctrl);</p>
<p>end;</p>
<p>IDImage:</p>
<p></font><font face="宋体" lang="ZH-CN"> ……</font><font face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> end; </p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> ……</font><font face="Arial"></p>
<p>WriteListEnd; </p>
<p>end;</p>
<p>finally.</p>
<p>Free; </p>
<p>end; </p>
<p>FileStream.Free; </p>
<p>end; </p>
<p> </p>
<p>20.3.2.2 BLOB</font><font face="宋体" lang="ZH-CN">字段与图形图像</p>
<p> </p>
<p> 在多媒体数据库中处理得比较多的是图形图像,因此早期的多媒体数据库在扩展关系数据库时往往是增加一个图像字段。</font><font
face="Arial">BLOB</font><font face="宋体" lang="ZH-CN">字段是以二进制数据存储方式,因此它完全可以表达图形图像数据。</p>
<p> 在</font><font face="Arial">TBlobField</font><font face="宋体" lang="ZH-CN">对象中提供了</font><font
face="Arial">LoadFromBitMap</font><font face="宋体" lang="ZH-CN">和</font><font
face="Arial">SaveToBitMap</font><font face="宋体" lang="ZH-CN">方法存取位图数据。它们在实现上都是使用</font><font
face="Arial">BlobStream</font><font face="宋体" lang="ZH-CN">对象。</p>
<p> </p>
<p></font><font face="Arial">procedure TBlobField.LoadFromBitmap(Bitmap: TBitmap);</p>
<p>var</p>
<p>BlobStream: TBlobStream;</p>
<p>Header: TGraphicHeader;</p>
<p>begin</p>
<p>BlobStream := TBlobStream.Create(Self, bmWrite);</p>
<p>try</p>
<p>if (DataType = ftGraphic) or (DataType = ftTypedBinary) then</p>
<p>begin</p>
<p>Header.Count := 1;</p>
<p>Header.HType := $0100;</p>
<p>Header.Size := 0;</p>
<p>BlobStream.Write(Header, SizeOf(Header));</p>
<p>Bitmap.SaveToStream(BlobStream);</p>
<p>Header.Size := BlobStream.Position - SizeOf(Header);</p>
<p>BlobStream.Position := 0;</p>
<p>BlobStream.Write(Header, SizeOf(Header));</p>
<p>end else</p>
<p>Bitmap.SaveToStream(BlobStream);</p>
<p>finally</p>
<p>BlobStream.Free;</p>
<p>end;</p>
<p>end;</p>
<p> </p>
<p>procedure TBlobField.SaveToBitmap(Bitmap: TBitmap);</p>
<p>var</p>
<p>BlobStream: TBlobStream;</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -