首页  编辑  

无名称构件的使用

Tags: /超级猛料/VCL/Control.控件使用开发和第三方控件/控件使用技巧/   Date Created:

无名称构件的使用

我曾在许多Delphi资料中看到这样的说法:每一个Component都必须有一个不为空的Name,用于和其他Component相区分。过去我也对这种说法深信不疑。但是看过《Mastering Delphi 6》后,我知道我错了。Component的Name属性可以是空的,特别是对于Menu Separator,Static Label,Bevel,Shape和Panel等等。虽然IDE会给所有的构件起一个默认的名称,不过你可以在Object Inspector中把它的Name清空,这样的后果是:

1.构件在Object Inspector和Object TreeView中将变成Unnamed或者Component<0>这样的表示方法;

2.该构件的声明将从Form的声明中完全删除;

3.如果用View As Text看看.DFM文件的定义,发现无名称的Component对象定义为这样的形式:

object : TMenuItem

caption = '-'

end

而一般的声明为:

object File1: TMenuItem

caption = 'File'

end

这个特点的真正好处在于,可以让Form的声明简洁许多,再也不会充斥大量无用的N1,N2之类标识符,从而混淆你的视线。当然,可执行文件的大小也会稍有减少。

不过,假如将Form上面所有Label的Name都设为空,那么运行该程序将产生一个错误,因为编译器看到声明中没有Label,所以不会将TLabel的有关TLabel的库函数连接进来。(编译器在绝大多数时候都很聪明,不过这个时候只能说它是自作聪明。)解决办法是至少保留一个有名字的Label。

我们甚至可以手动将Form中某个Component的声明删除。不用担心,在Form建立起来的时候这个Component不会消失,只是不能够用通常的办法来引用它了。真的有需要的时候,可以用Form1.FindComponent('Button1')这样的方法找到特定的构件。如果Form中的构件实在太多,可以用这个技巧来删除一部分不太重要的声明,保持单元的简洁。

其实,要减少Label声明的数量,用Delphi 6中新增的LabledEdit是一个行之有效的办法,而且LabeledEdit可以简化窗体的布局管理。不过,LabeledEdit只对Edit有效。要减少其他不需要响应事件和处理输入的构件(如Menu Separator,Panel和Bevel等等)的声明,就只能用这种方法。不同于一般的procedure或者function,在Delphi中属于某个类的方法称为method,它们的声明一般为AProcMethod:procedure(Sender:TObject) of object;

为什么一定要加上of object呢?实际上,Object Pascal中一般的函数指针就相当于普通的指针,而AProcMethod则是一个对指针,它在Delphi中有一个对应的类型:TMethod。

TMethod=record

Data, Code:Pointer;

end;

所以,我们在单元中可以这样:

procedure TForm1.Button1Click2(Sender:TObject);

begin

ShowMessage('Click2!');

end;

procedure TForm1.FormCreate(Sender:TObject);

var

Method:TMethod;

begin

Method.Data := Self;

Method.Code := MethodAddress('Button1Click2');

Button1.OnClick := TNotifyEvent(Method);

end;

当然,实际上只需要Button1.OnClick=Button1Click2即可;不过,这样可以让你明白在幕后发生的事情。值得注意的一点是,Button1Click2应该声明在published段(或者和其他构件的声明放在一起,因为默认作用域就是published),以便编译器为它产生RTTI信息,否则程序可能达不到预期的效果。