在Delphi中巧改窗体文件实现控件数组
来源:互联网 发布:tomcat 远程调试端口 编辑:程序博客网 时间:2024/06/13 21:16
delphi 开发的应用中,每一个窗体都有一个对应的窗体文件(.dfm),用来记录该窗体的属性以及窗体上所有控件的属性,以便在窗体关闭后能准确地重新生成窗体。几乎所有的DELPHI参考书都没有提到过该文件的具体情况,偶尔提到,也都泛泛而谈,因为窗体文件是二进制文件,只有在DELPHI提供的编辑环境中才能看到它的本来面目,对其进行操作可能会出现不可预知的错误;而且在大多数情况下,确实没有修改的必要。而本文谈到的和窗体文件密切相关。
要利用窗体文件,首先必须了解该类型文件的结构。窗体文件的结构很简单,朋友们可以生成一个窗体,随便放上一些控件,存盘后打开Unit1.dfm文件,就可以看到窗体文件是由关键字"object"和"end"构成的代码段,基本结构如下:
窗体文件是有序的,它的有序性表现如下:
其实,Controls和Components中控件的排列顺序和对应的窗体文件(.dfm)中控件描述代码段的排列顺序是相同的。前面我们谈到窗体文件是可以进行适当修改的,也就是说,我们可以根据需要调整窗体文件中控件描述代码段的排列顺序,让Controls和Components这两个控件数组全在掌握之中,这样我们就能清楚知道Controls[I]或Components[I]具体代表的是哪一个控件。下面举例说明。
比如,我们想让窗体Form1上的所有Tbutton灰化,最简单的方法是一句一句的编写代码:
Button1.Enabled := False; Button2.Enabled := False; … …
如果Tbutton数量很多,代码就变得很冗长。于是我们采用一个循环来实现:
for I := 0 to ControlCount -1 do if Controls[I] is Tbutton Then (Controls[I] as Tbutton).Enabled := False;
现在我们有了更有效的方法,首先打开窗体文件(Form1.dfm),调整Tbutton的排列顺序,让所有Tbutton的代码段(Object…end)都排在一起,然后数一下前面其它控件代码段的个数,设为n,n-1就是第一个Button在Controls(Components)数组中的位置,这样程序就很简单:
下一个例子更能体现利用这一规律的优越性。在编写Socket通信程序的时候,我们通常需要将用户输入的信息按照一定的顺序形成字符串,然后发送给服务器,服务器再根据事先约定的顺序解包,提取出内容,进行入库或其它操作。在形成字符串时,一般都是直接写代码,比如:
这里有两个问题需要注意:一是在调整控件描述代码段顺序时,一定要遵照文中提到的窗体文件的有序性规则,比如试图将一个TButton控件的描述代码放在一个TLabel控件的描述代码前面是不可能的;另外请大家注意Controls和Components的区别,窗体文件中,控件间的父子关系可以通过缩进的格式很明显的看出来,在计算控件在数组中的位置时,一定要考虑控件间的层次关系,如果使用Controls,就应该只对同级控件进行计数,如果是Components,则应包括所有的控件。
要利用窗体文件,首先必须了解该类型文件的结构。窗体文件的结构很简单,朋友们可以生成一个窗体,随便放上一些控件,存盘后打开Unit1.dfm文件,就可以看到窗体文件是由关键字"object"和"end"构成的代码段,基本结构如下:
object 控件名:类名属性1 =属性值属性2 =属性值 … end并且支持嵌套。Delphi在记录控件属性时,只记录修改过的属性,举一个例子,比如对一个标签控件(label1)的缺省描述如下:
object Label1: TLabelLeft = 256 Top = 80 Width = 32 Height = 13 Caption = Label1 End记录的五个属性都是随开发者拖放的位置和顺序不同而变化的,其它属性由于没有修改过,都是缺省值,所以不必记录。
窗体文件是有序的,它的有序性表现如下:
object 窗体名:Tform 窗体属性1=属性值 窗体属性2=属性值 。。。 。。。
// 以下是TgraphControl类型的控件
object 控件名:类名 控件属性1=属性值 控件属性2=属性值 。。。 。。。 end object 控件名:类名 控件属性1=属性值 控件属性2=属性值 。。。 。。。 end 。。。 。。。
// 以下是TwinControl类型的控件
object控件名:类名控件属性1=属性值控件属性2=属性值。。。。。。endobject控件名:类名控件属性1=属性值控件属性2=属性值。。。。。。end
// 以下是其它类型的控件
object控件名:类名控件属性1=属性值控件属性2=属性值。。。。。。end在同一种类型的控件中,各控件排列的先后顺序和它被拖放到窗体上的先后顺序相同。这个顺序是可以人为修改的,我们正是通过修改这个顺序,来实现控件的数组化。下面将详细介绍。
熟悉VB的朋友肯定知道在VB中可以通过控件拷贝实现控件的数组化。而DELPHI中则没有这种功能。Delphi中可以使用Components, Controls两个控件数组在一定程度上模拟控件的数组化,比如:
for I := 1 to ControlCount-1 do if (Controls[I] is Tlabel) then (Controls[I] as Tlabel).Caption := Test;这段代码的功能是将窗体上所有Label的Caption属性设为Test;这是一种非常有用的方法,大家如果不太熟悉可以参考delphi帮助作进一步了解。这种方法有很多局限,最明显的是我们并不知道Controls[i]或Components[i]到底代表哪一个控件,只能用遍历的方法进行筛选,这不仅影响了程序执行的效率,也带来编程上的繁琐。
其实,Controls和Components中控件的排列顺序和对应的窗体文件(.dfm)中控件描述代码段的排列顺序是相同的。前面我们谈到窗体文件是可以进行适当修改的,也就是说,我们可以根据需要调整窗体文件中控件描述代码段的排列顺序,让Controls和Components这两个控件数组全在掌握之中,这样我们就能清楚知道Controls[I]或Components[I]具体代表的是哪一个控件。下面举例说明。
比如,我们想让窗体Form1上的所有Tbutton灰化,最简单的方法是一句一句的编写代码:
Button1.Enabled := False; Button2.Enabled := False; … …
如果Tbutton数量很多,代码就变得很冗长。于是我们采用一个循环来实现:
for I := 0 to ControlCount -1 do if Controls[I] is Tbutton Then (Controls[I] as Tbutton).Enabled := False;
现在我们有了更有效的方法,首先打开窗体文件(Form1.dfm),调整Tbutton的排列顺序,让所有Tbutton的代码段(Object…end)都排在一起,然后数一下前面其它控件代码段的个数,设为n,n-1就是第一个Button在Controls(Components)数组中的位置,这样程序就很简单:
for I:= n-1 to n-1+ButtonNum do (Controls[I] as Tbutton).Enabled := False;代码的效率和简洁比以前有了很大提高。其中ButtonNum是Button的个数。
下一个例子更能体现利用这一规律的优越性。在编写Socket通信程序的时候,我们通常需要将用户输入的信息按照一定的顺序形成字符串,然后发送给服务器,服务器再根据事先约定的顺序解包,提取出内容,进行入库或其它操作。在形成字符串时,一般都是直接写代码,比如:
InfoS := ;//用于存放字符串。if Edit1.Text $#@60; $#@62; then InfoS := InfoS + Edit1.Text;else begin Application.Message(请填写必要信息); Exit; end;if Edit2.Text $#@60; $#@62; then InfoS := InfoS + Edit2.Text;else begin Application.Message(请填写必要信息); Exit;end;如果录入的项目多,这种方法会使代码冗长不堪。现在我们可以先调整窗体文件中Edit框描述代码段的顺序,让它们排列在一起,并确定第一个Edit框在Controls控件数组中的位置(方法入前),设为n-1(其中n表示排在Edit框前面的控件的描述代码段个数),编写如下代码实现:
for I := n-1 to n-1+EditNum do if ((Controls[I] as TEdit).Text $#@60; $#@62; ) then InfoS := InfoS + (Controls[I] as Tedit).Text; else begin Application.Message(请填写必要信息); Exit; end; //其中EditNum表示Edit框的个数。还有其它很多方面的应用,在这里就不一一赘述了。这实际上就是彻底实现了控件的数组化,而且这个数组还可以包含不同类型的控件。
这里有两个问题需要注意:一是在调整控件描述代码段顺序时,一定要遵照文中提到的窗体文件的有序性规则,比如试图将一个TButton控件的描述代码放在一个TLabel控件的描述代码前面是不可能的;另外请大家注意Controls和Components的区别,窗体文件中,控件间的父子关系可以通过缩进的格式很明显的看出来,在计算控件在数组中的位置时,一定要考虑控件间的层次关系,如果使用Controls,就应该只对同级控件进行计数,如果是Components,则应包括所有的控件。
当然,这种方法也有它的弊端,首先需要调整窗体文件顺序,其次程序的可读性会受到影响,所以大家在使用这种方法时应多写帮助。
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;type TForm1 = class(TForm) Panel1: TPanel; Button2: TButton; Button1: TButton; Scrollbox1: TScrollBox; procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button2Click(Sender: TObject);var i: Integer;begin for i := 0 to Panel1.ControlCount - 1 do begin end;end;procedure TForm1.FormCreate(Sender: TObject);varI:integer;temp:TEdit;beginfor I:=0 to 2 dobegintemp:=TEdit.Create(ScrollBox1);temp.Parent:=ScrollBox1;temp.Top:=temp.Height*i*2+50;temp.Text:='can be clear?'end;end;procedure TForm1.Button1Click(Sender: TObject);varI:integer;beginfor I:= 0 to ScrollBox1.ControlCount-1 dobeginif ScrollBox1.Controls[i] is TEdit thenTEdit(ScrollBox1.Controls[i]).Clear;end;end;end.
for i:=0 to Controlcount-1 dobegin if Controls[i].ClassName='TEdit' then (Controls[i] as TEdit).Text:=inttostr(i);end;
0 0
- 在Delphi中巧改窗体文件实现控件数组
- Delphi实现窗体控件自由移动
- delphi下实现控制其它窗体中的控件
- delphi下实现控制其它窗体中的控件
- delphi下实现控制其它窗体中的控件[转]
- delphi下实现控制其它窗体中的控件
- 用Delphi简单实现创建控件数组
- Delphi实现透明窗体
- delphi 实现可移动异形窗体(附项目文件)
- 用API函数在DELPHI中实现“非典型”窗体
- 用API函数在DELPHI中实现“非典型”窗体
- 用API函数在DELPHI中实现“非典型”窗体
- DELPHI也可以实现控件数组,用定义数组变量实现控件数组
- PHP解析Delphi 窗体文件
- DELPHI也可以实现控件数组,用定义数组变量实现控件数
- 在delphi中怎么样使控件群随窗体大小的改变而改变?谢谢。
- delphi窗体动态设计 在系统运行时动态更改控件属性
- C# 实现控件在不同窗体之间的引用
- JQuery Easy-UI 实现动态分页
- 开发环境搭建<->--ping通网络
- Java隐藏特性
- setOnClickListener 问题
- AndEngine:关于Texture的质量(2)
- 在Delphi中巧改窗体文件实现控件数组
- 测试数据没有insert到oracle数据库
- 【Python】之 Openers和Handlers
- 类的多态,动态类型,动态绑定
- C++:浅说模板定义
- springAOP原理
- 数据挖掘推荐书籍
- 征稿受阻下的行动启示
- JSP和Servlet知识随记(一)