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事件的處理過程來實現。
實現腳本語言擴展的基本方法與存取擴展類似,但它還要加擴展媒體信息轉換為文本,並插入到部件的腳本描述中。