时间:2011-11-16 | 栏目:Delphi教程 | 点击:次
3. 动态DFM文件应用之二:超媒体系统脚本语言设计
超媒体脚本语言设计是超媒体系统设计的重要内容。脚本语言必须能够表达卡片中的多种媒体对象,必须是可编程,可理解的,必须是可执行的,应该可以由脚本语言生成超媒体系统中的卡片和链。
DFM文件可以看作是超媒体系统的卡片,DFM脚本能够表达DFM文件中的多种控制,也就是说能够表达卡片中的多种媒体对象,再加上DFM脚本的对象式表达,可编辑性,可转换为DFM文件,因此用作超媒体系统脚本语言较好的形式。
ObjectBinaryToText和ObjectTextToBinary过程提供了在部件和DFM脚本之间相互转化的功能,ObjectResourceToText和ObjectTextToResoure过程提供了DFM文件和DFM脚本之间相互转化的功能。这样就可以在应用程序中自如实现超媒体卡片和超媒体脚本语言相互转化。
下面是卡片和脚本语言相互转化的程序:
procedure TMDIChild.CardToScript;
var
In, Out: TStream;
begin
In := TMemoryStream.Create;
Out := TMemoryStream.Create;
try
In.WriteComponentRes(Self.ClassName, Self);
ObjectResourceToText(In, out);
ScriptForm.ScriptEdit.Lines.LoadFromStream(Out);
finally
In.Free;
Out.Free;
end;
end;
ScriptEdit是个文本编辑器,它的Lines属性是TStrings类型的对象。
procedure TScriptForm.ScriptToCard;
var
In, Out: TStream;
begin
In := TMemoryStream.Create;
Out := TMemoryStream.Create;
try
ScriptForm.ScriptEdit.Lines.SaveToFromStream(In);
ObjectTextToResource(In, out);
In.ReadComponentRes(DesignWin);
finally
In.Free;
Out.Free;
end;
end;
这两段程序是对整个卡片,即窗体级,进行转换的。ObjectBinaryToText和ObjectTextToBinary过程可以细化到部件级的转换。因此超媒体脚本语言的编辑可以细化到媒体对象级。
4. 超媒体编辑和表现系统与动态DFM文件的扩展
超媒体系统的媒体编辑与卡片管理有其特殊的需求,比如链接需求。这时采用已有的窗体部件和媒体部件并按常规的DFM文件处理就显得力不从心了。解决这个矛盾有两套方案:
● 利用Delphi部件开发技术,继承和开发新的部件增加新的超媒体特有的属性和处理方法
● 扩展DFM文件结构,使之能按自己的需要任意地存取和转换部件和DFM文件
前者是充分利用Delphi的面向对象部件开发技术,在存取和转换等处理上仍旧与常规DFM文件相同。而后者需要DFM的存取和转换上作比较大的改动。下文介绍扩展DFM文件的思路。
扩展动态DFM文件的总体思路是降低处理操作的数据的颗粒度,即从原先窗体级降低到部件级。
下面是存取操作的扩展示范:
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事件的处理过程来实现。
实现脚本语言扩展的基本方法与存取扩展类似,但它还要加扩展媒体信息转换为文本,并插入到部件的脚本描述中。