ReadComponent方法主要是调用ReadComponent方法从Reader对象的流中读取一连串相关联的部件并分解相互引用关系
procedure TReaderReadComponents(AOwner AParent: TComponent;
Proc: TReadComponentsProc)
var
Component: TComponent;
begin
Root := AOwner;
Owner := AOwner;
Parent := AParent;
BeginReferences;
try
while not EndOfList do
begin
ReadSignature;
Component := ReadComponent(nil)
Proc(Component)
end;
FixupReferences;
finally
EndReferences;
end;
end;
ReadComponents首先用AOwner和AParent参数给RootOwner和Parent赋值用于重建各部件的相互引用然后用一个While循环读取部件并用由Proc传入的方法进行处理在重建引用关系时用了BeginReferencesFixUpReferences和EndReferences嵌套模式
ReadRootComponent方法从Reader对象的流中将部件及其拥有的部件全部读出如果Component参数为nil则创建一个相同类型的部件最后返回该部件
function TReaderReadRootComponent(Root: TComponent) TComponent;
function FindUniqueName(const Name: string) string;
begin
…
end;
var
I: Integer;
Flags: TFilerFlags;
begin
ReadSignature;
Result := nil;
try
ReadPrefix(Flags I)
if Root = nil then
begin
Result := TComponentClass(FindClass(ReadStr))Create(nil)
ResultName := ReadStr;
end else
begin
Result := Root;
ReadStr; { Ignore class name }
if csDesigning in ResultComponentState then
ReadStr else
ResultName := FindUniqueName(ReadStr)
end;
FRoot := Result;
if GlobalLoaded <> nil then
FLoaded := GlobalLoaded else
FLoaded := TListCreate;
try
FLoadedAdd(FRoot)
FOwner := FRoot;
Include(FRootFComponentState csLoading)
Include(FRootFComponentState csReading)
FRootReadState(Self)
Exclude(FRootFComponentState csReading)
if GlobalLoaded = nil then
for I := to FLoadedCount do TComponent(FLoaded[I])Loaded;
finally
if GlobalLoaded = nil then FLoadedFree;
FLoaded := nil;
end;
GlobalFixupReferences;
except
RemoveFixupReferences(Root )
if Root = nil then ResultFree;
raise;
end;
end;
ReadRootComponent首先调用ReadSignature读取Filer对象标签然后在try…except循环中执行读取任务如果Root参数为nil则用ReadStr读出的类名创建新部件并以流中读出部件的Name属性否则忽略类名并判断Name属性的唯一性最后用Root的ReadState方法读取属性和其拥有的拥有并处理引用关系
SetName方法和OnSetName事件
因为在OnSetName事件中Name参数是var型的所以可以用OnSetName事件处理过程修改所读部件的名字而OnSetName事件处理过程是在SetName方法中实现的
procedure TReaderSetName(Component: TComponent; var Name: string)
begin
if Assigned(FOnSetName) then FOnSetName(Self Component Name)
ComponentName := Name;
end;
SetName方法和OnSetName事件在动态DFM文件的编程中有很重要的作用
TReader的错误处理
TReader的错误处理是由Error方法和OnError事件的配合使用完成的OnError 事件处理过程的Handled参数是var型的布尔变量通过将Handled设为True或False可影响TReader 的错误处理OnError事件处理过程是在Error方法中调用的
function TReaderError(const Message: string) Boolean;
begin
Result := False;
if Assigned(FOnError) then FOnError(Self Message Result)
end;
FindMethod和OnFindMethod事件
有时在程序运行期间给部件的方法指针(主要是事件处理过程)动态赋值是很有用的这样就能动态地改变部件响应事件的方式在流中读取部件捍做到一点就要利用OnFindMehtod事件OnFIndMethod事件是在FindMethod方法中被调用的
function TReaderFindMethod(Root: TComponent;
const MethodName: string) Pointer;
var
Error: Boolean;
begin
Result := RootMethodAddress(MethodName)
Error := Result = nil;
if Assigned(FOnFindMethod) then FOnFindMethod(Self MethodName Result
Error)
if Error then PropValueError;
end;
OnFindMethod 方法除了可以给部件的MethodName所指定的方法指针动态赋值外还可修改Error参数来决定是否处理Missing Method错误方法中调用的MehtodAddress 方法定义在TObject中它是个很有用的方法它可以得到对象中定义的public方法的地址FindMethod方法和OnFindMethod事件在动态DFM的编程中有很重要的作用
Delphi对象式数据管理应用实例
Delphi 无论是其可视化设计工具还是可视化部件类库(VCL)都处处渗透了对象存储技术本节将从Delphi可视化设计内部机制VCL中的数据存储BLOB数据操作和动态生成部件的存储几方面介绍对象存储功能的实例应用
Delphi 动态DFM文件及部件的存取在超媒体系统中的应用
Delphi的可视化设计工具是同其部件类库紧密结合在一起的
每个部件只有通过一段注册程序并通过Delphi的Install Component功能才能出现在Component Palette上部件的属性才有可能出现在Object Inspector窗口中部件的属性编辑器才能被Delphi环境使用因为这种浑然天成的关系DFM文件存取必然得到VCL在程序上的支持
DFM文件的部件存取是Delphi可视化设计环境中文件存取的中心问题因为Delphi可视化设计的核心是窗体的设计每个窗体对应一个库单元是应用程序的模块窗体在磁盘上的存储就是DFM文件
DFM文件结构我们前面介绍过了它实际上是存储窗体及其拥有的所有部件的属性这种拥有关系是递归的问题在于如何将这些属性数据与程序中的变量(属性)代码联系起来
在Delphi中处理这种联系的过程分为两种情况设计时和运行时
在设计时建立联系表现为读取DFM 文件建立DFM文件中的部件及其属性与可视化设计工具(Object Inspector窗体设计窗口和代码编辑器)的联系也就是说让这些部件及其属性能出现在这些窗口中并与代码中的属性定义联系起来分解联系表现为存储DFM文件将窗体窗口中的部件及其属性写入DFM文件
在运行时主要是建立联系的过程即读取DFM文件这时DFM文件不是作为独立的磁盘文件而是以应用程序资源中的RCDATA类型的二进制数据存在建立联系的过程表现为将资源中的部件及其属性与应用程序中的对象及其数据域联系起来其过程为根据DFM中的部件类名创建对象再将用DFM中的部件属性值给程序中的部件属性赋值当然要完成这一过程还必须在代码中有相应的窗体定义因为方法等代码是不存入部件的
VCL对读取DFM文件在代码上的支持是通过Stream对象和Filer对象达到的在 和节中我们可以看到Stream对象和Filer对象中有大量的用于存取部件及其属性的方法尤其在TReader对象中还有关于错误处理和动态的方法赋值的方法下面我们就通过程序实例介绍存取DFM文件方法步骤和注意事项
返回目录DELPHI基础教程
编辑推荐
Java程序设计培训视频教程
JEE高级框架实战培训视频教程
Visual C++音频/视频技术开发与实战
Oracle索引技术
ORACLEG数据库开发优化指南
Java程序性能优化让你的Java程序更快更稳定
C嵌入式编程设计模式
Android游戏开发实践指南
[] [] [] []