DELPHI基础教程:开发Delphi对象式数据管理功能(二)[1]

如题所述

第1个回答  2022-10-16

   TResourceStream对象

  TResourceStream对象是另一类MemoryStream对象 它提供对Windows 应用程序资源的访问 因此称它为资源流 TResourceSream也是从TCustomMemoryStream 继承的 因此在TCustomMemoryStream对象的基础上 定义了与指定资源模块或资源文件建立连接的构造方法 并且还覆盖了Write 以实现向资源文件中写数据

  下面介绍TResourceStream的实现

   私有域

  TResourceStream没有定义新的属性 但它在private部分定义了两个数据域HResInfo和HGlobol和一个私有方法Initialize 它们的定义如下

  TResourceStream = class(TCustomMemoryStream)

  private

  HResInfo: HRSRC;

  HGlobal: THandle;

  procedure Initialize(Instance: THandle; Name ResType: PChar)

  …

  end;

  HRSRC是描述Windows资源信息的结构句柄 HGlobal变量代表资源所在模块的句柄 如果操作的是应用程序资源 HGlohal就代表EXE程序的句柄 如果是动态链接库(DLL) 则HGlobal 代表动态链接库的句柄 TResourceStream对象使用这两上变量访问应用程序或动态链接库中的资源

  Initialize方法是TResourceStream对象内部使用的 它的构造方法Create和CreateFromID都是调用Initialize方法完成对TResourceStream的初始化 它的实现如下

  procedure TResourceStream Initialize(Instance: THandle; Name ResType: PChar)

  procedure Error;

  begin

  raise EResNotFound Create(FmtLoadStr(SResNotFound [Name]))

  end;

  begin

  HResInfo := FindResource(Instance Name ResType)

  if HResInfo = then Error;

  HGlobal := LoadResource(Instance HResInfo)

  if HGlobal = then Error;

  SetPointer(LockResource(HGlobal) SizeOfResource(Instance HResInfo))

  end;

  该方法实现中 首先调用Windows函数FoundResource得到由参数Instance指定的模块中的名为Name和类型为ResType的资源 然后调用LoadResource将资源调用内存 并返回该资源在内存中的句柄 最后 将该资源复制到ResourceStream中 方法的Instance参数代表要调用的资源所在的模块句柄 模块可以是可执行文件 也可以是动态链接库 如果在读取资源时没在模块中发现要找的资源则产生异常事件

   构造方法Create和CreateFromID

  这两个方法在实现上没有大的不同 顾名思义 第一个方法是通过资源名构造TResourceStream; 第二个方法通过资源ID构造TResourceStream 而且在实现过程中 它们都调用了Initialize方法 下面是它们的实现

  constructor TResourceStream Create(Instance: THandle; const ResName: string;

  ResType: PChar)

  begin

  inherited Create;

  Initialize(Instance PChar(ResName) ResType)

  end;

  constructor TResourceStream CreateFromID(Instance: THandle; ResID: Integer;

  ResType: PChar)

  begin

  inherited Create;

  Initialize(Instance PChar(ResID) ResType)

  end;

  这两个方法中都有Instance参数 该参数值的含义在Insitialize中介绍过

   Write方法

  TResourceStream的Write方法只完成一件事 就产生这个异常事件 其实现如下

  function TResourceStream Write(const Buffer; Count: Longint) Longint;

  begin

  raise EStreamError CreateRes(SCantWriteResourceStreamError)

  end;

  从方法实现中可以看到 TSourceStream对象是不允许写数据的 一旦往资源流中写数据将产生异常事件

   析构方法Destroy

  该方法产生给资源解锁 然后释放该资源 最后调用继承的Destroy方法释放ResourceStream 其实现如下

  destructor TResourceStream Destroy;

  begin

  UnlockResource(HGlobal)

  FreeResource(HResInfo)

  inherited Destroy;

  end;

  回顾Initialize方法 我们不难发现

  ● ResourceStream没有额外地给资源重新分配内存 而是直接使用HGlobal句柄所指 的内存域

  ● ResourceStream中的资源在流的生存期 始终是Lock状态 因此要根据Windows 的内存使用规则合理安排ResourceStream的使用

  ● ResourceStream只是用于访问应用程序和动态链接库中的资源的

  在Classes在单元中提供了InternalReadComponentRes函数 该函数使用了TResourceStream对象从Delphi应用程序中读取部件 Delphi是将窗体和部件信息放在模块资源的RCDATA段的

   TBlobStream对象

  从Delphi 数据库开发平台这个意义上说 TBlobStream 对象是个很重要的对象 TBlobStream对象提供了修改TBlobField TBytesField或TVarBytesField中数据的技术 开发者可以象对待文件或流那样在数据库域中读写数据

  传统数据库发展的一个重要趋向是往多媒体数据库发展 目前比较著名和流行的数据库都支持多媒体功能 多媒体数据存储中的一大难点是数据结构不规则 数据量大 各大数据库产品是采用BLOB技术解决多媒体数据存储中的问题 Delphi的TBlobStream对象的意义就在于 一方面可以使Delphi应用程序充分利用多媒体数据库的数据管理能力 另一方面又能利用Object Pascal的强大程序设计能力给多媒体数据库提供全方向的功能扩展余地

  使用TBlobStream对象可以在多媒体数据库的BLOB字段存储任意格式的数据 一般说来 许多多媒体数据库只能支持图像 语音或者OLE服务器支持的数据 利用TBlobStream则不同 只要是程序能够定义的数据格式 它都能在BLOB字段中读写 而不需要其它辅助工具

  TBlobStream用构造方法Create建立数据库域和BLOB流的联接 用Read或Write 方法访问和改变域中的内容 用Seek方法 在域中定位 用Truncate方法删除域中当前位置起所有的数据

   TBlobStream的属性和方法

  TBlobStream对象从TStream直接继承 没有增添新的属性 它覆盖了Read Write 和Seek方法 提供了对BLOB字段的访问操作 它增添了Truncate方法以实现BLOB字段中的删除操作

   Read方法

  声明

function Read(var Buffer; Count: Longint) Longint;

  Read方法从数据库域的当前位置起复制Count个字节的内容到Buffer中 Buffer也必须至少分配Count个字节 Read方法返回实际传输的字节数 因为传输的字节数可能小于Count 所以需要选择符的边界判断

lishixinzhi/Article/program/Delphi/201311/25100

DELPHI基础教程:开发Delphi对象式数据管理功能(二)[1]
在Classes在单元中提供了InternalReadComponentRes函数 该函数使用了TResourceStream对象从Delphi应用程序中读取部件 Delphi是将窗体和部件信息放在模块资源的RCDATA段的 TBlobStream对象 从Delphi 数据库开发平台这个意义上说 TBlobStream 对象是个很重要的对象 TBlobStream对象提供了修改TBlobField TBytesField或TVarBy...

DELPHI基础教程:数据访问部件的应用及编程(二)[1]
DatabaseName属性是说明数据库应用程序所操作的数据库的名字 它可以是由BDE定义的数据库的别名 显式说明的数据库文件所在的磁盘路径或者由TDatabase部件定义的一个数据库名 DatabaseName属性常常是一个由BDE定义的数据库的别名 使用由BDE定义的数据库的别名代替数据库实际所在的路径和名字 好处是当实际的...

DELPHI基础教程:Delphi开发数据库应用程序概述(一)[2]
Delphi是Borland公司于 年底发布的用于开发数据库应用程序的工具 它是面向对象的 它是目前开发客户\/服务器数据库应用程序的强有力的工具 Delphi在Window 以上版本的系统环境下运行 目前具有两个版本 Delphi的标准版本和客户\/服务器版本 标准版本包含一个Borland Database Engine的局部拷贝 它允许用户创建能访...

DELPHI基础教程:剪贴板和动态数据交换(二)[1]
界面中包含一个DDE会话部件DDEClientConv 和DDE项目部件DDEClientItem 用于建立和维护DDE联接 一个RadioGroup控件和其中的两个无线电按钮AutoRadio ManualRadio 用于设置联接模式 一个GroupBox控件和其中的两个按钮RequestBtn和PokeBtn 用于控制数据的申请和发送 其中RequestBtn在自动模式下变灰 一个文本框Memo ...

DELPHI基础教程:开发Delphi对象式数据管理功能(四)[1]
procedure ReadSignature; ReadSignature方法从流中读取部件之前首先调用ReadSignature方法 在载入对象之前检测标签 Reader对象就能防止疏忽大意 导致读取无效或过时的数据 Filer标签是四个字符 对于Delphi 该标签是 TPF ReadPrefix方法 声明 procedure ReadPrefix(var Plags: TFilerFlags; var AChild Pos: ...

DELPHI基础教程:数据访问部件的应用及编程(二)[2]
然后在表中进行检索 检索出与查找值相匹配的记录来 如果我们是在Paradox或dBASE数据库中的表中查找记录 那么查找值所对应的字段必须是表中的关键字段或辅助索引字段 如果查找SQL数据库服务器中的表 那么查找值必须是表的IndexFieldNames属性中指定的字段 lishixinzhi\/Article\/program\/Delphi\/201311\/25158 ...

DELPHI基础教程:数据浏览部件的应用及编程(一)[2]
TDBGrid部件和TDBEdit部件一样 它们是专门用来显示和编辑数据库表中的数据的 但TDBGrid部件的功能更强大一些 它可以以网格的形式显示数据库表中全部记录的所有字段信息 用TDBGrid显示数据库表中的记录信息 返回目录 DELPHI基础教程 编辑推荐 Java程序设计培训视频教程 J EE高级框架实战培训视频教程 Visual ...

DELPHI基础教程:开发Delphi对象式数据管理功能(五)[1]
第二十章 开发Delphi对象式数据管理功能(五)写DFM文件的过程 WriteComponentResFie 该过程带有两个参数FileName和Instance FileName参数指定要写入的DFM文件名 Instance参数是TComponent类型的 它指定要写入的部件名 一般是TForm对象的子类 该过程将Instance部件和其拥有的所有部件写入DFM文件 这个过程的意义...

Delphi7 从入门到精通目录
第一部分:基础入门 第1章:Delphi 7环境与集成开发环境(IDE)的初步认识 第2章:深入理解Delphi编程语言,掌握基本语法和数据类型 第3章:运行时库的使用,理解其核心功能和作用 第4章:核心库类详解,为开发提供强大支持 第5章:探索可视控件的世界,构建用户界面的基础 第6章:如何设计并实现用户...

DELPHI基础教程:Delphi自定义部件开发(一)[2]
① 为部件创建库单元 可选择File\/New… 在New Items对话框中选择Unit Delphi将创建一个新文件 并在代码编辑器中打开它 ② 在已有库单元中增加部件 只须选择File\/OPen为已有库单元选择源代码 在该库单元中只能包含部件代码 如果该库单元中有一个窗体 将产生错误 ⑵ 继承一个部件对象 每个部件都是T...

相似回答
大家正在搜