控件转移在工具栏制作中的应用
李鲲程 范春梅
随着可视化编程技术的推广,应用程序的界面设计逐步趋向规范化、简便化。所谓“规范化”是指应用程序具有统一的用户界面,如都包括下拉式选单、状态栏、工具栏等;“简便化”就是让使用者用起来更方便。而工具栏在这两方面都起着不可忽视的作用,因此,工具栏的样式也就越来越多,最开始只有固定工具栏,后来出现了可拖动工具栏,现在浮动工具栏又脱颖而出。
前一段时间,我们所在的单位用Delphi开发一套光盘数据库系统,用户需求中明确要求要有灵活好用的工具栏。在开发过程中我们采用了MDI(Multiple
Document Interface)结构,主窗体MainForm上包括一个工具栏,工具栏上是一些快捷按钮用来激发子窗体上各个控件的事件,当主窗体创建子窗体ChildForm1,子窗体ChildForm1又创建子窗体ChildForm2,而后子窗体ChildForm1关闭,这时问题出现了,如果你要用主窗体MainForm上的工具栏上的按钮去控制ChildForm2上的控件事件,Delphi就会出现错误信息。
为此,我们想过在ChildForm2上建立一个工具栏来控制它自己的事件,这样做在功能上虽然行得通,但是这样的工具栏既不符合Windows下应用软件的界面的习惯,用户用起来也不方便,因为子窗体内的工具栏会随着子窗体的滚动条而上下滚动,很不方便。后来我们想到了控件的转移方法。所谓转移是指,控件最初是在ChildForm2中,但它的Visible属性为False,也就是说它是不可视的,当ChildForm2被创建时工具栏上的快捷按钮被移到MainForm的工具栏上的适当位置,虽然快捷按钮的位置是在MainForm上,但它的功能却和在ChildForm2上没有区别,而且当ChildForm2窗口被关闭以后,MainForm上的快捷按钮会自动消失,不会给应用程序的运行增加任何麻烦。控件转移程序的源代码如下:
procedure movebutton(win:twincontrol);
var
i,j:integer;
begin
for i:=0 to componentcount-1 do
if components[i] is tspeedbutton then
tspeedbutton(components[i]).parent:=win;
if win=form1.ToolBar1 then
for j:=0 to win.ControlCount-1 do
if j=0 then
win.Controls[j].left:=0
else
win.Controls[j].left:=win.Controls[j-1].left+23;
end;
针对初学者,对上面的程序给出以下几点说明:
1.componentcount、components[index]是Tcompanent的属性,这里TChildForm继承了这一属性。
2.对于Tform、Tpanel、Tgroupbox、Ttabcontrol、Tpagecontrol等对象而言它们是放在它们上面的控件对象的Parent,同样,当改变控件对象的Parent时,控件的位置自然要随之而改变,tspeedbutton(components[i]).parent:=win;就是起到这样的作用。
3.在这段程序中既用到了components[index]属性,又用到了controls[index]属性,它们都用来代表程序中用到的控件,但有很大的区别。前者表示对象中的所有控件,但它通常代表的控件不带有任何属性,比如Left、Visible,而后者只能代表它的Child控件,而且可以带有该控件的大部分属性。
这段代码虽然简单,但是它的用处还是很大的,我们在制作浮动工具栏时又用到了这种算法。所谓浮动工具栏就是指工具栏浮动于应用程序之上,用户可以根据自身的需要随意摆放它的位置。具体方法是先建立一个始终悬浮于表面的ToolBox(BorderStyle属性为bsToolWindow,FormStyle属性为fsStayOnTop),当需要使用浮动工具栏时显示ToolBox,同时将需要的快捷按钮转移到ToolBox上来,这样一个浮动工具栏就很快“生产”出来了。