📄 055.htm
字号:
<p>InsertControl(Ctrl);</p>
<p>end;</p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p> 动态插入控制的优点是可以在任何时刻、任意位置插入任意数量的任何类型的控制。因为应用程序需求在很多情况下是在程序运行中才知道的,所以动态插入控制就显得很重要。而且在很多情况下,需要保存这些界面元素,留待程序再次调用。例如应用程序界面的定制、系统状态的保存、对话框的保存等。这时生成动态</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件是最佳选择。</p>
<p> 动态插入控制的不足之处是在插入控制前,无法直观地看到控制的大小、风格、位置等,也就是动态插入控制的过程是非可视化的。但可以借助于静态</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件的可视化设计。这就是生成和使用动态</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件的第二种方法。也就是在应用程序运行前,在</font><font
face="Arial">Delphi</font><font face="宋体" lang="ZH-CN">开发环境中,使用可视化开发工具设计所需窗口或部件的样式,以</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件保存。然后在应用程序运行过程中,将</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件读入内存。</font><font
face="Arial">Delphi</font><font face="宋体" lang="ZH-CN">的</font><font face="Arial">Stream</font><font
face="宋体" lang="ZH-CN">对象和</font><font face="Arial">Filer</font><font
face="宋体" lang="ZH-CN">对象在读取</font><font face="Arial">DFM</font><font
face="宋体" lang="ZH-CN">文件时,会根据</font><font face="Arial">DFM</font><font
face="宋体" lang="ZH-CN">文件的内容自动创建部件及其拥有的所有部件。</p>
<p> 在使用动态</font><font face="Arial">DFM</font><font face="宋体"
lang="ZH-CN">文件时有两点需要注意。</font><font face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN"> ●</font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN">每一个动态插入的控制或部件必须在程序中调用</font><font
face="Arial">RegisterClass</font><font face="宋体" lang="ZH-CN">进行注册</p>
<p> ●</font><font face="Arial"> </font><font face="宋体" lang="ZH-CN">读入</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件自动创建部件后,如果调用了</font><font
face="Arial">InsertControl</font><font face="宋体" lang="ZH-CN">方法,</font><font
face="Arial"> </font><font face="宋体" lang="ZH-CN">则在关闭窗口时要调用</font><font
face="Arial">RemoveControl</font><font face="宋体" lang="ZH-CN">方法移去该控制,否则会产生异常事件</p>
<p> </p>
<p> </font><font face="Arial">2. </font><font face="宋体" lang="ZH-CN">动态</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件应用之一:超媒体系统的卡片设计</p>
<p> </font><font face="Arial">Delphi</font><font face="宋体" lang="ZH-CN">多种类型的可视部件,如文本部件、编辑部件、图形图像部件、数据库部件、媒体媒放部件和</font><font
face="Arial">OLE</font><font face="宋体" lang="ZH-CN">部件等,每一种部件在屏幕中占据一定的区域,具有相当丰富的表现能力,可以作为卡片中的一种媒体,因此可以利用这些可视部件进行超媒体系统的卡片设计。</p>
<p> 超媒体卡片设计要求卡片中的媒体数目和媒体种类是不受限制的,而且必须能够修改和存取卡片,因此,采用动态</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件是比较合适的。而且如果利用</font><font
face="Arial">Stream</font><font face="宋体" lang="ZH-CN">对象,将卡片存储在数据库</font><font
face="Arial">BLOB</font><font face="宋体" lang="ZH-CN">字段中,就为把超文本与关系数据库技术结合起来创造了契机。</p>
<p> 下面是超媒体卡片设计子系统中的部分源程序,它演示了如何创建对象、插入对象和存取动态</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件。</p>
<p> ⑴</font><font face="Arial"> </font><font face="宋体" lang="ZH-CN">在应用程序中注册对象</p>
<p> </p>
<p></font><font face="Arial">procedure TMainForm.FormCreate(Sender: TObject);</p>
<p>begin</p>
<p>RegisterClass(TLabel);</p>
<p>RegisterClass(TEdit);</p>
<p>RegisterClass(TMemo);</p>
<p>RegisterClass(TButton);</p>
<p>RegisterClass(TPanel);</p>
<p>RegisterClass(TPanelP);</p>
<p>RegisterClass(TBitBtn);</p>
<p></font><font face="宋体" lang="ZH-CN">…</p>
<p></font><font face="Arial">end;</p>
<p> </p>
<p></font><font face="宋体" lang="ZH-CN">⑵</font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN">创建和插入对象</p>
<p> </p>
<p></font><font face="Arial">procedure TMDIChild.FormClick(Sender: TObject);</p>
<p>var</p>
<p>Ctrl : TControl;</p>
<p>Point: TPoint;</p>
<p>begin</p>
<p>GetCursorPos(Point);</p>
<p>Point := BackGround.ScreenToClient(Point);</p>
<p>case CurToolIndex of</p>
<p>1 : begin</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">Ctrl := TLabel.Create(self);</font><font face="宋体"
lang="ZH-CN"></p>
<p></font><font face="Arial">TLabel(Ctrl).AutoSize := False;</p>
<p>TLabel(ctrl).Caption := 'Label'+S;</p>
<p>TLabel(ctrl).Name := 'Label 1';</p>
<p>TLabel(ctrl).Top := Point.Y;</p>
<p>TLabel(ctrl).Left := Point.X;</p>
<p>TLabel(Ctrl).Height := Round(100*Res/1000/Ratio);</p>
<p>TLabel(Ctrl).Width := Round(600*Res/1000/Ratio);</p>
<p>TLabel(Ctrl).Color := clWhite;</p>
<p>TLabel(Ctrl).Font.Color := clBlack;</p>
<p>TLabel(Ctrl).Font.Name := 'Roman';</p>
<p>TLabel(Ctrl).Font.Height := -TLabel(Ctrl).Height;</p>
<p>TLabel(Ctrl).Font.Pitch := fpFixed;</p>
<p>TLabel(Ctrl).Enabled := False;</p>
<p>TLabel(Ctrl).OnClick := LabelClick;</p>
<p>TLabel(Ctrl).OnMouseMove := ReportPos;</p>
<p>BackGround.InsertControl(Ctrl);</p>
<p>CurTool.Down := False;</p>
<p>CurTool := nil;</p>
<p></font><font face="宋体" lang="ZH-CN">…</p>
<p></font><font face="Arial">end;</p>
<p>2: begin</p>
<p>Ctrl := TEdit.Create(self);</p>
<p>TEdit(ctrl).AutoSize := True;</p>
<p>TEdit(ctrl).Top := Point.Y;</p>
<p>TEdit(ctrl).Left := Point.X;</p>
<p>TEdit(Ctrl).Height := 20;</p>
<p>BackGround.InsertControl(Ctrl);</p>
<p></font><font face="宋体" lang="ZH-CN">…</font><font face="Arial"></p>
<p>end;</p>
<p>3: </p>
<p></font><font face="宋体" lang="ZH-CN">…</p>
<p></font><font face="Arial">end;</p>
<p>end; </font><font face="宋体" lang="ZH-CN"></p>
<p> </p>
<p> ⑵</font><font face="Arial"> </font><font face="宋体" lang="ZH-CN">存取动态</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件</p>
<p> </p>
<p></font><font face="Arial">procedure TMainForm.FileOpen(Sender: TObject);</p>
<p>begin</p>
<p>if OpenDialog.Execute then</p>
<p>begin</p>
<p>DesignWin := TMDIChild.Create(Application);</p>
<p>ReadComponentResFile(OpenDialog.FileName, DesignWin);</p>
<p>DesignWin.Init;</p>
<p>FileName := OpenDialog.FileName; </font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">DesignWin.Caption := FFileName;</font><font face="宋体"
lang="ZH-CN"></p>
<p></font><font face="Arial">end;</p>
<p>end;</p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p> </font><font face="Arial">DesignWin</font><font face="宋体" lang="ZH-CN">是在</font><font
face="Arial">TMainForm</font><font face="宋体" lang="ZH-CN">中定义的</font><font
face="Arial">TMDIChild</font><font face="宋体" lang="ZH-CN">类型的窗体部件,是卡片设计平台;</font><font
face="Arial">FFileName</font><font face="宋体" lang="ZH-CN">是私有变量,用来保存当前编辑的卡片文件名。</font><font
face="Arial">DesignWin</font><font face="宋体" lang="ZH-CN">的</font><font face="Arial">Init</font><font
face="宋体" lang="ZH-CN">方法实现如下:</p>
<p> </p>
<p></font><font face="Arial">procedure TMDIChild.Init;</p>
<p>var</p>
<p>I: Integer;</p>
<p>Ctrl: TControl;</p>
<p>begin</p>
<p>BackGround.BringToFront;</p>
<p>with BackGround do</p>
<p>for I:= 0 to ControlCount - 1 do</p>
<p>if Controls[I].Name <> ''then</p>
<p>ObjectIns.ObjectList.Items.AddObject(Controls[I].Name, Controls[I]);</p>
<p>end;</p>
<p></font> <font face="宋体" lang="ZH-CN"></p>
<p> </font><font face="Arial">BackGround</font><font face="宋体" lang="ZH-CN">是</font><font
face="Arial">TPanel</font><font face="宋体" lang="ZH-CN">类型的部件,所有的动态创建对象都插入到</font><font
face="Arial">BackGround</font><font face="宋体" lang="ZH-CN">中,所以,后面调用</font><font
face="Arial">BackGround.InsertControl(Ctrl)</font><font face="宋体" lang="ZH-CN">;</font><font
face="Arial">ObjectIns</font><font face="宋体" lang="ZH-CN">是个仿</font><font
face="Arial">Delphi </font><font face="宋体" lang="ZH-CN">的媒体属性编辑器。</p>
<p> 动态</font><font face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件的存储过程是这样的:</p>
<p> </p>
<p></font><font face="Arial">procedure TMainForm.FileSave(Sender: TObject);</p>
<p>begin</p>
<p>if DesignWin.CurControl <> nil then</p>
<p>DesignWin.CurControl.Enabled := True;</p>
<p>WriteComponentResFile(FFilename, DesignWin);</p>
<p>DesignWin.Caption := FileName;</p>
<p>end;</p>
<p>end;</p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p> 因为在</font><font face="Arial">DesignWin</font><font face="宋体"
lang="ZH-CN">的</font><font face="Arial">Init</font><font face="宋体" lang="ZH-CN">方法中调用了</font><font
face="Arial">InsertControl</font><font face="宋体" lang="ZH-CN">方法,所以在关闭</font><font
face="Arial">DesignWin</font><font face="宋体" lang="ZH-CN">窗口时要相应地调用</font><font
face="Arial">RemoveControl</font><font face="宋体" lang="ZH-CN">,否则在关闭</font><font
face="Arial">DesignWin</font><font face="宋体" lang="ZH-CN">窗口时会产生内存错误。</p>
<p> </p>
<p></font><font face="Arial">procedure TMDIChild.FormCloseQuery(Sender: TObject; var
CanClose: Boolean);</p>
<p>var</p>
<p>I: Integer;</p>
<p>Ctrl: TControl;</p>
<p>Removed: Boolean;</p>
<p>begin</p>
<p>if Modified = True then</p>
<p>if MessageDlg('Close the form?', mtConfirmation,</p>
<p>[mbOk, mbCancel], 0) = mrCancel then</p>
<p>CanClose := False;</p>
<p>if CanClose = True then</p>
<p>begin</p>
<p>repeat</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">removed := False;</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">I := 0;</p>
<p>repeat</p>
<p>if BackGround.Controls[I].Name <> '' then</p>
<p>begin</p>
<p>BackGround.RemoveControl(BackGround.Controls[I]);</p>
<p>Removed := True;</p>
<p>end;</p>
<p>I := I + 1</p>
<p>until (I >= BackGround.ControlCount) or (Removed = True);</p>
<p>until (Removed = False);</p>
<p>SendMessage(ObjectIns.Handle, WM_MDICHILDCLOSED, 0, 0);</p>
<p>end;</p>
<p>end;</p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p> </font><font face="Arial">3. </font><font face="宋体" lang="ZH-CN">动态</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件应用之二:超媒体系统脚本语言设计</p>
<p> 超媒体脚本语言设计是超媒体系统设计的重要内容。脚本语言必须能够表达卡片中的多种媒体对象,必须是可编程,可理解的,必须是可执行的,应该可以由脚本语言生成超媒体系统中的卡片和链。</p>
<p> </font><font face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件可以看作是超媒体系统的卡片,</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">脚本能够表达</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件中的多种控制,也就是说能够表达卡片中的多种媒体对象,再加上</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">脚本的对象式表达,可编辑性,可转换为</font><font
face="Arial">DFM</font><font face="宋体" lang="ZH-CN">文件,因此用作超媒体系统脚本语言较好的形式。</p>
<p> </font><font face="Arial">ObjectBinaryToText</font><font face="宋体"
lang="ZH-CN">和</font><font face="Arial">ObjectTextToBinary</font><font face="宋体"
lang="ZH-CN">过程提供了在部件和</font><font face="Arial">DFM</font><font
face="宋体" lang="ZH-CN">脚本之间相互转化的功能,</font><font face="Arial">ObjectResourceToText</font><font
face="宋体" lang="ZH-CN">和</font><font face="Arial">ObjectTextToResoure</font><font
face="宋体" lang="ZH-CN">过程提供了</font><font face="Arial">DFM</font><font
face="宋体" lang="ZH-CN">文件和</font><font face="Arial">DFM</font><font
face="宋体" lang="ZH-CN">脚本之间相互转化的功能。这样就可以在应用程序中自如实现超媒体卡片和超媒体脚本语言相互转化。</p>
<p> </p>
<p> 下面是卡片和脚本语言相互转化的程序:</p>
<p> </p>
<p></font><font face="Arial">procedure TMDIChild.CardToScript;</p>
<p>var</p>
<p>In, Out: TStream;</p>
<p>begin</p>
<p>In := TMemoryStream.Create;</p>
<p>Out := TMemoryStream.Create;</p>
<p>try</p>
<p>In.WriteComponentRes(Self.ClassName, Self);</p>
<p>ObjectResourceToText(In, out);</p>
<p>ScriptForm.ScriptEdit.Lines.LoadFromStream(Out);</p>
<p>finally</p>
<p>In.Free;</p>
<p>Out.Free;</p>
<p>end;</p>
<p>end;</p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p> </font><font face="Arial">ScriptEdit</font><font face="宋体" lang="ZH-CN">是个文本编辑器,它的</font><font
face="Arial">Lines</font><font face="宋体" lang="ZH-CN">属性是</font><font
face="Arial">TStrings</font><font face="宋体" lang="ZH-CN">类型的对象。</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -