汇编 | Java | C# | Delphi | C/C++ |

DELPHI基础教程 第二十章 开发Delphi对象式数据管理功能(二)

第二十章 开发Delphi对象式数据管理功能(二)

内容来自dedecms

20.1.6 TResourceStream对象 

织梦好,好织梦

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

织梦内容管理系统

下面介绍TResourceStream的实现 本文来自织梦

  1. 私有域 copyright dedecms

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

copyright dedecms

 

织梦内容管理系统

TResourceStream = class(TCustomMemoryStream) 内容来自dedecms

private 织梦好,好织梦

HResInfo: HRSRC;

内容来自dedecms

HGlobal: THandle;

本文来自织梦

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

本文来自织梦

dedecms.com

end;

dedecms.com

  织梦好,好织梦

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

内容来自dedecms

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

dedecms.com

  本文来自织梦

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

本文来自织梦

 

织梦好,好织梦

procedure Error; copyright dedecms

begin

dedecms.com

raise EResNotFound.Create(FmtLoadStr(SResNotFound, [Name])); 织梦好,好织梦

end;

织梦内容管理系统

  dedecms.com

begin

织梦好,好织梦

HResInfo := FindResource(Instance, Name, ResType);

本文来自织梦

if HResInfo = 0 then Error;

copyright dedecms

HGlobal := LoadResource(Instance, HResInfo); 织梦好,好织梦

if HGlobal = 0 then Error;

copyright dedecms

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

本文来自织梦

end; 织梦好,好织梦

  织梦内容管理系统

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

织梦好,好织梦

  2. 构造方法CreateCreateFromID

织梦内容管理系统

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

copyright dedecms

 

织梦好,好织梦

constructor TResourceStream.Create(Instance: THandle; const ResName: string; copyright dedecms

ResType: PChar);

dedecms.com

begin

dedecms.com

inherited Create; 织梦内容管理系统

Initialize(Instance, PChar(ResName), ResType); dedecms.com

end; dedecms.com

 

内容来自dedecms

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

织梦内容管理系统

ResType: PChar);

织梦内容管理系统

begin

dedecms.com

inherited Create;

dedecms.com

Initialize(Instance, PChar(ResID), ResType); 织梦好,好织梦

end; 织梦内容管理系统

 

内容来自dedecms

  这两个方法中都有Instance参数,该参数值的含义在Insitialize中介绍过。 内容来自dedecms

  3. Write方法

内容来自dedecms

  TResourceStreamWrite方法只完成一件事,就产生这个异常事件,其实现如下: dedecms.com

  织梦内容管理系统

function TResourceStream.Write(const Buffer; Count: Longint): Longint; 本文来自织梦

begin 织梦内容管理系统

raise EStreamError.CreateRes(SCantWriteResourceStreamError);

dedecms.com

end; 内容来自dedecms

  本文来自织梦

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

  4. 析构方法Destroy

织梦内容管理系统

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

copyright dedecms

 

内容来自dedecms

destructor TResourceStream.Destroy;

copyright dedecms

begin 织梦好,好织梦

UnlockResource(HGlobal);

织梦好,好织梦

FreeResource(HResInfo); 织梦好,好织梦

inherited Destroy;

dedecms.com

end; dedecms.com

  织梦好,好织梦

  回顾Initialize方法,我们不难发现:

织梦好,好织梦

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

dedecms.com

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

内容来自dedecms

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

  织梦好,好织梦

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

dedecms.com

 

本文来自织梦

20.1.7 TBlobStream对象

织梦内容管理系统

 

copyright dedecms

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

织梦内容管理系统

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

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

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

copyright dedecms

  织梦内容管理系统

20.1.7.1 TBlobStream的属性和方法 织梦好,好织梦

 

本文来自织梦

  TBlobStream对象从TStream直接继承,没有增添新的属性。它覆盖了ReadWrite Seek方法,提供了对BLOB字段的访问操作;它增添了Truncate方法以实现BLOB字段中的删除操作。 内容来自dedecms

  1. Read方法

织梦好,好织梦

  声明:function Read(var Buffer; Count: Longint): Longint; 内容来自dedecms

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

织梦好,好织梦

  2. Write方法

内容来自dedecms

  声明:function Write(const Buffer; Count: Longint); override; Longint; 本文来自织梦

Write方法从Buffer中向数据库域的当前位置复制Count个字节的内容。Buffer必须分配有Count个字节的内存空间,函数返回实际传输的字节数,传输过程也要进行选择符边界判断。

dedecms.com

  3. Seek方法 copyright dedecms

  声明:function Seek(Offset: Longint; Origin: Word): Longint; 织梦好,好织梦

  Seek方法重新设置BLOB流中的指针位置。如果Origin的值是soFromBeginning,则新的指针位置是Offset; Origin的值是soFromCurrent,则新的指针位置是Position+Offset;如果Origin的值是SoFromCurrent,则新的指针位置是Size+Offset。函数返回新的指针位置值。当Origin0(SoFromBegin)时,Offset的值必须大于等于零; Origin的值为2(SoFromEnd)Offset的值必须小于等于零。 dedecms.com

  4. Truncate方法

织梦内容管理系统

  声明:procedure Truncate;

dedecms.com

Truncate方法撤消TBlobFieldTBytesFieldTVarBytesField中从当前位置起的数据。 本文来自织梦

  5. Create方法 本文来自织梦

  声明:constructor Create(Field: TBlobField; Mode: TBlobStreamMode); 织梦好,好织梦

  Create方法使用Field参数建立BLOB流与BLOB字段的联接。Mode 的值可为bmReadbmWritebmReadWrite copyright dedecms

  织梦内容管理系统

20.1.7.2 TBlobStream的实现原理 本文来自织梦

  copyright dedecms

  说明TBlobStream对象的实现原理,不可避免地要涉及它的私有域,下面是私有域的定义:

本文来自织梦

  织梦好,好织梦

TBlobStream = class(TStream)

dedecms.com

private

内容来自dedecms

FField: TBlobField; 内容来自dedecms

FDataSet: TDataSet;

dedecms.com

FRecord: PChar; 织梦好,好织梦

FBuffer: PChar;

内容来自dedecms

FFieldNo: Integer; 织梦好,好织梦

FOpened: Boolean; copyright dedecms

FModified: Boolean;

织梦内容管理系统

FPosition: Longint; dedecms.com

本文来自织梦

public dedecms.com

内容来自dedecms

end; dedecms.com

 

织梦好,好织梦

  FField是与BLOB流相联的数据库BLOB域,该域用于BLOB流的内部访问。FDataSet是代表FField所在的数据库,它可以是TTable部件,也可以是TQuery 部件。FRecordFBuffer都是BLOB流内部使用的缓冲区,用于存储FField所在记录的数据,该数据记录中不包含BLOB数据,TBlobStream使用FRecord作为调用BDE API函数的参数值。FFieldNo代表BLOB字段的字段号,也用于BDE API的参数传递,FOpenedFMocified都是状态信息,FPosition表示BLOB流的当前位置,下面介绍TBlobStream方法实现。

内容来自dedecms

  1. Create方法和Destroy方法的实现

内容来自dedecms

  Create方法的功能主要是建立BlobStream流与BLOB字段的联系并初始化某些私有变量。其实现如下: 内容来自dedecms

   织梦内容管理系统

constructor TBlobStream.Create(Field: TBlobField; Mode: TBlobStreamMode); 织梦内容管理系统

var 织梦好,好织梦

OpenMode: DbiOpenMode; copyright dedecms

begin

织梦内容管理系统

FField := Field;

copyright dedecms

FDataSet := Field.DataSet;

dedecms.com

FRecord := FDataSet.ActiveBuffer;

本文来自织梦

FFieldNo := Field.FieldNo;

织梦内容管理系统

if FDataSet.State = dsFilter then

织梦内容管理系统

DBErrorFmt(SNoFieldAccess, [FField.DisplayName]);

dedecms.com

if not FField.FModified then 内容来自dedecms

begin

copyright dedecms

if Mode = bmRead then dedecms.com

begin 内容来自dedecms

FBuffer := AllocMem(FDataSet.RecordSize);

本文来自织梦

FRecord := FBuffer; 内容来自dedecms

if not FDataSet.GetCurrentRecord(FBuffer) then Exit; 本文来自织梦

OpenMode := dbiReadOnly;

织梦内容管理系统

end else

织梦好,好织梦

begin

本文来自织梦

if not (FDataSet.State in [dsEdit, dsInsert]) then DBError(SNotEditing); dedecms.com

OpenMode := dbiReadWrite;

dedecms.com

end;

dedecms.com

Check(DbiOpenBlob(FDataSet.Handle, FRecord, FFieldNo, OpenMode)); dedecms.com

end;

织梦内容管理系统

FOpened := True;

内容来自dedecms

if Mode = bmWrite then Truncate;

内容来自dedecms

end; 织梦好,好织梦

 

内容来自dedecms

 该方法首先是用传入的Field参数给FFieldFDataSetFRecordFFieldNo赋值。方法中用AllocMem按当前记录大小分配内存,并将指针赋给FBuffer,用DataSet部件的GetCurrentRecord方法,将记录的值赋给FBuffer,但不包括BLOB数据。 织梦内容管理系统

  方法中用到的DbiOpenBlob函数是BDEAPI函数,该函数用于打开数据库中的BLOB字段。 dedecms.com

  最后如果方法传入的Mode参数值为bmWrite,就调用Truncate将当前位置指针以后的 织梦内容管理系统

数据删除。 copyright dedecms

  分析这段源程序不难知道:

dedecms.com

  ● 读写BLOB字段,不允许BLOB字段所在DataSet部件有Filter,否则产生异常事件 本文来自织梦

  ● 要读写BLOB字段,必须将DataSet设为编辑或插入状态

copyright dedecms

  如果BLOB字段中的数据作了修改,则在创建BLOB 流时,不再重新调用DBiOpenBlob函数,而只是简单地将FOpened置为True,这样可以用多个BLOB 流对同一个BLOB字段读写 dedecms.com

  织梦内容管理系统

  Destroy方法释放BLOB字段和为FBuffer分配的缓冲区,其实现如下:

织梦好,好织梦

  dedecms.com

destructor TBlobStream.Destroy; 内容来自dedecms

begin

dedecms.com

if FOpened then

copyright dedecms

begin

内容来自dedecms

if FModified then FField.FModified := True; copyright dedecms

if not FField.FModified then

copyright dedecms

DbiFreeBlob(FDataSet.Handle, FRecord, FFieldNo);

dedecms.com

end;

内容来自dedecms

if FBuffer <> nil then FreeMem(FBuffer, FDataSet.RecordSize); 织梦好,好织梦

if FModified then copyright dedecms

try

copyright dedecms

FField.DataChanged; copyright dedecms

except

dedecms.com

Application.HandleException(Self);

织梦内容管理系统

end; 织梦内容管理系统

end; 织梦内容管理系统

  织梦内容管理系统

  如果BLOB流中的数据作了修改,就将FFieldFModified置为True;如果FFieldModifiedFalse就释放BLOB字段,如果FBuffer不为空,则释放临时内存。最后根据FModified的值来决定是否启动FField的事件处理过程DataChanged 织梦好,好织梦

  不难看出,如果BLOB字段作了修改就不释放BLOB字段,并且对BLOB 字段的修改只有到Destroy时才提交,这是因为读写BLOB字段时都避开了FField,而直接调用BDE API函数。这一点是在应用BDE API编程中很重要,即一定要修改相应数据库部件的状态。

内容来自dedecms

  2. ReadWrite方法的实现

本文来自织梦

  ReadWrite方法都调用BDE API函数完成数据库BLOB字段的读写,其实现如下:

织梦内容管理系统

   内容来自dedecms

function TBlobStream.Read(var Buffer; Count: Longint): Longint; 内容来自dedecms

var

内容来自dedecms

Status: DBIResult; copyright dedecms

begin

本文来自织梦

Result := 0;

本文来自织梦

if FOpened then

织梦好,好织梦

begin

本文来自织梦

Status := DbiGetBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition, dedecms.com

Count, @Buffer, Result); copyright dedecms

case Status of

织梦内容管理系统

DBIERR_NONE, DBIERR_ENDOFBLOB: 本文来自织梦

begin

织梦内容管理系统

if FField.FTransliterate then

织梦内容管理系统

NativeToAnsiBuf(FDataSet.Locale, @Buffer, @Buffer, Result); dedecms.com

Inc(FPosition, Result); copyright dedecms

end;

dedecms.com

DBIERR_INVALIDBLOBOFFSET: copyright dedecms

{Nothing};

dedecms.com

else

dedecms.com

DbiError(Status); 织梦好,好织梦

end; 内容来自dedecms

end; 织梦好,好织梦

end;

dedecms.com

 

织梦内容管理系统

  Read方法使用了BDE APIDbiGetBlob函数从FDataSet中读取数据,在本函数中,各参数的含义是这样的:FDataSet.Handle代表DataSetBDE句柄,FReacord表示BLOB字段所在记录,FFieldNo表示BLOB字段号,FPosition表示要读的的数据的起始位置,Count表示要读的字节数,Buffer是读出数据所占的内存,Result是实际读出的字节数。该BDE函数返回函数调用的错误状态信息。

本文来自织梦

  Read方法还调用了NativeToAnsiBuf进行字符集的转换。 内容来自dedecms

  dedecms.com

function TBlobStream.Write(const Buffer; Count: Longint): Longint; copyright dedecms

var copyright dedecms

Temp: Pointer;

copyright dedecms

begin 织梦好,好织梦

Result := 0;

织梦好,好织梦

if FOpened then

本文来自织梦

begin

内容来自dedecms

if FField.FTransliterate then 内容来自dedecms

begin

dedecms.com

GetMem(Temp, Count); 内容来自dedecms

try copyright dedecms

AnsiToNativeBuf(FDataSet.Locale, @Buffer, Temp, Count);

织梦好,好织梦

Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition, 本文来自织梦

Count, Temp)); 织梦内容管理系统

finally copyright dedecms

FreeMem(Temp, Count); dedecms.com

end; 本文来自织梦

end else

dedecms.com

Check(DbiPutBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition,

织梦内容管理系统

Count, @Buffer));

内容来自dedecms

Inc(FPosition, Count); 织梦内容管理系统

Result := Count;

copyright dedecms

FModified := True; copyright dedecms

end; 织梦内容管理系统

end; copyright dedecms

  本文来自织梦

Write方法调用了BDE APIDbiPutBlob函数实现往数据库BLOB字段存储数据。

织梦内容管理系统

该函数的各参数含义如下:

copyright dedecms

 

本文来自织梦

20.2 调用函数DbiPutBlob的各传入参数的含义

内容来自dedecms

 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

本文来自织梦

   参数名           含义 本文来自织梦

────────────────────────────── dedecms.com

  FDataSetHandle 写入的数据库的BDE句柄

本文来自织梦

  FRecord 写入数据的BLOB字段所在的记录

织梦内容管理系统

FFieldNo BLOB字段号 本文来自织梦

  FPosition 写入的起始位置

织梦好,好织梦

  Count 写入的数据的字节数 内容来自dedecms

  Buffer 所写入的数据占有的内存地址 内容来自dedecms

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 本文来自织梦

 

织梦好,好织梦

  方法中还根据FFieldFTransliterate的值判断是否进行相应的字符集转换,最后移动BLOB流的位置指针,并将修改标志FModified置为True

内容来自dedecms

3. SeekGetBlobSize方法的实现

本文来自织梦

  Seek方法的功能主要是移动BLOB流的位置指针。GetBlobSize方法是私有的,在Seek方法中被调用,其功能是得到BLOB数据的大小。它们的实现如下:

织梦好,好织梦

  本文来自织梦

function TBlobStream.GetBlobSize: Longint; 织梦好,好织梦

begin

copyright dedecms

Result := 0;

织梦内容管理系统

if FOpened then

织梦内容管理系统

Check(DbiGetBlobSize(FDataSet.Handle, FRecord, FFieldNo, Result));

dedecms.com

end; 织梦内容管理系统

 

织梦好,好织梦

function TBlobStream.Seek(Offset: Longint; Origin: Word): Longint; 内容来自dedecms

begin 织梦内容管理系统

case Origin of

内容来自dedecms

0: FPosition := Offset; 织梦好,好织梦

1: Inc(FPosition, Offset); 织梦好,好织梦

2: FPosition := GetBlobSize + Offset;

织梦内容管理系统

end; copyright dedecms

Result := FPosition;

copyright dedecms

end; 内容来自dedecms

  织梦好,好织梦

GetBlobSize调用了BDE APIDbiGetBlobSize函数,该函数的参数的含义同前面的API函数相同。 织梦好,好织梦

  4. Truncate方法

织梦好,好织梦

该方法是通过调用BDE API函数实现的。其实现如下: 本文来自织梦

 

本文来自织梦

procedure TBlobStream.Truncate; 本文来自织梦

begin 织梦好,好织梦

if FOpened then

内容来自dedecms

begin

dedecms.com

Check(DbiTruncateBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition)); copyright dedecms

FModified := True;

copyright dedecms

end;

内容来自dedecms

end; dedecms.com

 

织梦好,好织梦

  该方法从BLOB流的当前位置起删除所有数据,并设置修改标志FModifiedTrue。在Delphi VCL中许多部件特别是数据库应用方面的部件都用BDE API函数完成对数据库的访问,如Data AccessData Control部件。各种数据库部件都是BDE API函数外层的包装简化了对数据库的访问操作。BDE API中还提供了避开BDE配置工具在程序中直接处理Alias(建立、修改、删除等)的函数支持,这也是部件所没有提供的。在Delphi数据库应用安装程序中,这些Alias操作函数无疑是相当重要的。有关BDE API函数的详细介绍,可阅读Delphi2.0 Client/Server Suite所带的BDE API 帮助文件。 dedecms.com

 

dedecms.com

  copyright dedecms

20.2 读写对象的实现原理和应用

织梦内容管理系统

 

织梦内容管理系统

  读写对象(Filer)包括TFiler对象、TReader对象和TWriter对象。TFiler对象是文件读写的基础对象,在应用程序中使用的主要是TReaderTWriterTReaderTWriter对象都直接从TFiler对象继承。TFiler对象定义了Filer对象的基本属性和方法。

内容来自dedecms

  Filer对象主要完成两大功能: 织梦好,好织梦

  ● 存取窗体文件和窗体文件中的部件

织梦内容管理系统

  ● 提供数据缓冲,加快数据读写操作 本文来自织梦

 

本文来自织梦

20.2.1 TFiler对象

织梦好,好织梦

 

dedecms.com

 TFiler对象是TReaderTWriter的抽象类,定义了用于部件存储的基本属性和方法。它定义了Root属性,Root指明了所读或写的部件的根对象,它的Create方法将Stream对象作为传入参数以建立与Stream对象的联系, Filer对象的具体读写操作都是由Stream对象完成。因此,只要是Stream对象所能访问的媒介都能由Filer对象存取部件。TFiler 对象还提供了两个定义属性的方法:DefinePropertyDefineBinaryProperty,这两个方法使对象能读写不在部件published部分定义的属性。

织梦好,好织梦

  因为Filer对象主要用于存取Delphi的窗体文件和窗体文件中的部件,所以要清楚地理解Filer对象就要清楚Delphi 窗体文件(DFM文件)的结构。 织梦内容管理系统

  DFM文件是用于Delphi存储窗体的。窗体是Delphi可视化程序设计的核心。窗体对应Delphi应用程序中的窗口,窗体中的可视部件对应窗口中的界面元素,非可视部件如TTableTOpenDialog,对应Delphi应用程序的某项功能。Delphi应用程序的设计实际上是以窗体的设计为中心。因此,DFM文件在Delphi应用设计中也占很重要的位置。窗体中的所有元素包括窗体自身的属性都包含在DFM文件中。

dedecms.com

  在Delphi应用程序窗口,界面元素是按拥有关系相互联系的,因此树状结构是最自然的表达形式;相应地,窗体中的部件也是按树状结构组织;对应在DFM文件中,也要表达这种关系。DFM文件在物理上,是以二进制方式存储的,在逻辑上则是以树状结构安排各部件的关系。Delphi编辑窗口支持以文本方式显示DFM文件。从该文本中可以看清窗体的树状结构。下面是DFM文件的文本显示:

织梦内容管理系统

  本文来自织梦

  Object Form1: TForm1 内容来自dedecms

Left = 72 内容来自dedecms

Top = 77

本文来自织梦

ActiveControl = DBIMage1 dedecms.com

织梦内容管理系统

Object Panell: TPanel copyright dedecms

Left = 6

内容来自dedecms

织梦内容管理系统

Object DBLabel1: TDBText

本文来自织梦

本文来自织梦

end dedecms.com

Object DBImage1: TDBImage dedecms.com

织梦好,好织梦

end dedecms.com

end

本文来自织梦

Object Panel2: TPanel

dedecms.com

Left = 6 织梦好,好织梦

本文来自织梦

Object Label1: TLable 本文来自织梦

内容来自dedecms

end 织梦内容管理系统

end copyright dedecms

Object Panel3: TPanel

内容来自dedecms

Left = 6 dedecms.com

本文来自织梦

Object DBLabel2: TDBText

织梦好,好织梦

copyright dedecms

end

织梦内容管理系统

end dedecms.com

end

dedecms.com

  关于DFM文件中存储属性值的规则,请参见自定义部件开发这一章。

织梦内容管理系统

  对照TFiler对象的属性。Root属性就表示部件树的根──窗体。Filer对象的许多方法都是读从根起始的树中所有的部件。Ancestor属性表示根的祖先对象,IgnoreChildren属性则是读部件时忽略根的子结点。 织梦好,好织梦

  下面介绍Filer对象的属性和方法。

dedecms.com

精彩推荐
热点内容
最近更新