首页 考试吧论坛 Exam8视线 考试商城 网络课程 模拟考试 考友录 实用文档 求职招聘 论文下载
2011中考 | 2011高考 | 2012考研 | 考研培训 | 在职研 | 自学考试 | 成人高考 | 法律硕士 | MBA考试
MPA考试 | 中科院
四六级 | 职称英语 | 商务英语 | 公共英语 | 托福 | 雅思 | 专四专八 | 口译笔译 | 博思 | GRE GMAT
新概念英语 | 成人英语三级 | 申硕英语 | 攻硕英语 | 职称日语 | 日语学习 | 法语 | 德语 | 韩语
计算机等级考试 | 软件水平考试 | 职称计算机 | 微软认证 | 思科认证 | Oracle认证 | Linux认证
华为认证 | Java认证
公务员 | 报关员 | 银行从业资格 | 证券从业资格 | 期货从业资格 | 司法考试 | 法律顾问 | 导游资格
报检员 | 教师资格 | 社会工作者 | 外销员 | 国际商务师 | 跟单员 | 单证员 | 物流师 | 价格鉴证师
人力资源 | 管理咨询师考试 | 秘书资格 | 心理咨询师考试 | 出版专业资格 | 广告师职业水平
驾驶员 | 网络编辑
卫生资格 | 执业医师 | 执业药师 | 执业护士
会计从业资格考试会计证) | 经济师 | 会计职称 | 注册会计师 | 审计师 | 注册税务师
注册资产评估师 | 高级会计师 | ACCA | 统计师 | 精算师 | 理财规划师 | 国际内审师
一级建造师 | 二级建造师 | 造价工程师 | 造价员 | 咨询工程师 | 监理工程师 | 安全工程师
质量工程师 | 物业管理师 | 招标师 | 结构工程师 | 建筑师 | 房地产估价师 | 土地估价师 | 岩土师
设备监理师 | 房地产经纪人 | 投资项目管理师 | 土地登记代理人 | 环境影响评价师 | 环保工程师
城市规划师 | 公路监理师 | 公路造价师 | 安全评价师 | 电气工程师 | 注册测绘师 | 注册计量师
缤纷校园 | 实用文档 | 英语学习 | 作文大全 | 求职招聘 | 论文下载 | 访谈 | 游戏
您现在的位置: 考试吧(Exam8.com) > 计算机等级考试 > 计算机二级 > Delphi > 复习资料 > 正文

2011等考Delphi:开发Delphi对象式数据管理功能

来源:考试吧Exam8.com) 2010-10-30 9:21:41 考试吧:中国教育培训第一门户 模拟考场
在本章中将介绍Stream对象和Filer对象的实现原理、应用方法以及在超媒体系统中的应用。这对于运用Delphi 开发高级应用是很重要的。

  下面是存取操作的扩展示范:

  var

  FileStream: TStream;

  I: Integer;

  begin

  FileStream := TFileStream.Create('OverView.Crd', fmOpenWrite);

  With TWriter.Create(FileStream, 4096) do

  try

  for I := 0 to DesignWin.ControlCount - 1 do

  begin

  WriteInteger(MMID[i]);

  WriteRootComponent(DesignWin.Controls[i]);

  { 写相应媒体扩展信息 }

  ……

  end;

  WriteListEnd;

  finally.

  Free;

  end;

  FileStream.Free;

  end;

  WriteInteger(MMID[i])语句是写入媒体标识。

  下面是相应的读扩展DFM的程序:

  var

  PropInfo: PPropInfo;

  Method : TMethod;

  FileStream: TStream;

  I: Integer;

  begin

  FileStream := TFileStream.Create('OverView.Crd', fmOpenRead);

  With TReader.Create(FileStream, 4096) do

  try

  while not EndOfList do

  begin

  case ReadInteger of

  IDText: begin

  Ctrl := TControl(ReadRootComponent(nil));

  PropInfo := GetPropInfo(Ctrl.ClassInfo, 'OnClick');

  Method.Code:= Self.MethodAddress(MethodName);

  Method.Data := Self;

  if Method.Code <> nil then

  SetMethodProp(Ctrl, PropInfo, Method);

  DesignWin.InsertControl(Ctrl);

  end;

  IDImage:

  ……

  end;

  ……

  WriteListEnd;

  end;

  finally.

  Free;

  end;

  FileStream.Free;

  end;

  SetMethodProp过程是用于重新联接控制和它的事件处理过程。类似的功能还可以用TReader对象的OnFindMethod事件的处理过程来实现。

  实现脚本语言扩展的基本方法与存取扩展类似,但它还要加扩展媒体信息转换为文本,并插入到部件的脚本描述中。

  20.3.2 数据库BLOB字段应用

  Delphi VCL提供了TBlobStream对象支持对数据库BLOB字段的存取。Delphi 的TBlobStream对象的作用在于一方面可以使Delphi应用程序充分利用多媒体数据库的数据管理能力。另一方面又能利用Delphi Object Pascal的程序设计能力给关系型多媒体数据库提供底层控制能力和全方位的功能扩展余地。

  20.3.2.1 TBlobStream的使用

  TBlobStream对象用一个TBlobField类型的对象作为参数来创建与BLOB字段相联的BLOB流,接着就可用流的存取方法在BLOB字段中存取数据。

  var

  BlobStream: TBlobStream;

  I: Integer;

  begin

  BlobStream := TBlobStream.Create(TBlobField(CardTable.Fields[10], bmWrite);

  With TWriter.Create(BlobStream, 4096) do

  try

  for I := 0 to DesignWin.ControlCount - 1 do

  begin

  WriteInteger(MMID[i]);

  WriteRootComponent(DesignWin.Controls[i]);

  { 写相应媒体扩展信息 }

  ……

  end;

  WriteListEnd;

  finally.

  Free;

  end;

  BlobStream.Free;

  CardTable.Post;

  end;

  Fields变量是表示数据库记录的字段数组,Fields[10]正是数据库的BLOB 字段。CardTable的Post方法将数据库的修改反馈到数据库的物理存储上。

  上面这段程序是超媒体卡片存储的部分源程序,我们就是将卡片保存在数据库BLOB字段中,实现将超文本和关系数据库两种数据管理方式结合起来。读卡片的程序如下:

  var

  PropInfo: PPropInfo;

  Method: TMethod;

  Blobtream: TStream;

  I: Integer;

  begin

  BlobStream := TBlobStream.Create(TBlobField(CardTable.Fields[10]), bmRead);

  With TReader.Create(BlobStream, 4096) do

  try

  while not EndOfList do

  begin

  case ReadInteger of

  IDText: begin

  Ctrl := TControl(ReadRootComponent(nil));

  PropInfo := GetPropInfo(Ctrl.ClassInfo, 'OnClick');

  Method.Code:= Self.MethodAddress(MethodName);

  Method.Data := Self;

  if Method.Code <> nil then

  SetMethodProp(Ctrl, PropInfo, Method);

  DesignWin.InsertControl(Ctrl);

  end;

  IDImage:

  ……

  end;

  ……

  WriteListEnd;

  end;

  finally.

  Free;

  end;

  FileStream.Free;

  end;

  20.3.2.2 BLOB字段与图形图像

  在多媒体数据库中处理得比较多的是图形图像,因此早期的多媒体数据库在扩展关系数据库时往往是增加一个图像字段。BLOB字段是以二进制数据存储方式,因此它完全可以表达图形图像数据。

  在TBlobField对象中提供了LoadFromBitMap和SaveToBitMap方法存取位图数据。它们在实现上都是使用BlobStream对象。

  procedure TBlobField.LoadFromBitmap(Bitmap: TBitmap);

  var

  BlobStream: TBlobStream;

  Header: TGraphicHeader;

  begin

  BlobStream := TBlobStream.Create(Self, bmWrite);

  try

  if (DataType = ftGraphic) or (DataType = ftTypedBinary) then

  begin

  Header.Count := 1;

  Header.HType := $0100;

  Header.Size := 0;

  BlobStream.Write(Header, SizeOf(Header));

  Bitmap.SaveToStream(BlobStream);

  Header.Size := BlobStream.Position - SizeOf(Header);

  BlobStream.Position := 0;

  BlobStream.Write(Header, SizeOf(Header));

  end else

  Bitmap.SaveToStream(BlobStream);

  finally

  BlobStream.Free;

  end;

  end;

  procedure TBlobField.SaveToBitmap(Bitmap: TBitmap);

  var

  BlobStream: TBlobStream;

  Size: Longint;

  Header: TGraphicHeader;

  begin

  BlobStream := TBlobStream.Create(Self, bmRead);

  try

  Size := BlobStream.Size;

  if Size >= SizeOf(TGraphicHeader) then

  begin

  BlobStream.Read(Header, SizeOf(Header));

  if (Header.Count <> 1) or (Header.HType <> $0100) or

  (Header.Size <> Size - SizeOf(Header)) then

  BlobStream.Position := 0;

  end;

  Bitmap.LoadFromStream(BlobStream);

  finally

  BlobStream.Free;

  end;

  end;

  程序中按两种方式存取数据,对于位图数据,数据的起点是流的Potition为0处,对于图形或其它类型的Blob数据,则以流的Position为SizeOf(Header) + 1处开始, 即多了个头信息。

  20.3.2.3 BLOB字段与文本

  Delphi BLOB字段中增加了大型文本的处理能力。可以在TBlobField和Strings中自由地交换数据。

  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对象之间传递数据。为此,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)就不行。

上一页  1 2 3 4 5 6 7 8 9  下一页
  相关推荐:2010年9月计算机等级考试试题及答案解析专题
       预告:名师解析2010年9月计算机等级考试试题答案
       2010年9月计算机等级考试成绩查询时间及入口
       2010年9月计算机等考成绩查询短信免费提醒开通
文章搜索
版权声明:如果计算机等级考试网所转载内容不慎侵犯了您的权益,请与我们联系800@exam8.com,我们将会及时处理。如转载本计算机等级考试网内容,请注明出处。