(delphi11最新学习资料) Object Pascal 学习笔记---第12章第3节 ( RTL 中的类引用 )

12.3.1 RTL 中的类引用**

System 单元和其他核心 RTL 单元声明了许多类引用,包括以下几种:

TClass = class of TObject;
ExceptClass = class of Exception;
TComponentClass = class of TComponent;
TControlClass = class of TControl;
TFormClass = class of TForm;

​ 特别是 TClass 类引用类型可用于存储对 Object Pascal 中编写的任何类的引用,因为每个类最终都是从 TObject 派生的。相反,TFormClass 引用则在基于 FireMonkey 或 VCL 的默认 Object Pascal 项目的源代码中使用。实际上,这两个库的 Application 对象的 CreateForm 方法作为参数需要要创建的窗体的类:

Application.CreateForm(TMyForm1, MyForm);

​ 第一个参数是一个类引用,第二个是将接收对创建的对象实例的引用的变量。

12.3.2 使用类引用创建组件

​ 在 Object Pascal 中,类引用有什么实际用途呢?能够在运行时使用数据类型是运行环境的基本能力。当你从Component Palette(组件面板)中选择一个新组件添加到窗体中时,你就选择了一种数据类型并创建了该数据类型的对象。(实际上,这就是开发环境在幕后为你做的事情)。

​ 为了让你更好地了解类引用是如何工作的,我创建了一个名为 ClassRef 的示例。这个示例显示的窗体非常简单。窗体的上半部分的面板中放置了三个单选按钮。当你选择其中一个单选按钮并单击窗体时,就可以创建按钮标签所示的三种类型的新组件:单选按钮、普通按钮和编辑框。要使程序正常运行,需要更改这三个组件的名称,因为组件名称必须是唯一的。窗体还必须有一个类引用字段:

private
  FControlType: TControlClass;
  FControlNo: Integer;

​ 每当用户点击三个单选按钮中的一个,第一个字段就会存储一个新的数据类型,从而改变其状态。以下是三种方法之一:

procedure TForm1.RadioButtonRadioChange(Sender: TObject);
begin
  FControlType := TRadioButton;
end;

​ 其他两个单选按钮的 OnChange 事件处理器与此类似,都将 TEdit 或 TButton 的值赋值给 FControlType 字段。类似的赋值也出现在窗体的 OnCreate 事件处理器中,用作初始化方法。当用户点击覆盖窗体大部分表面的 TLayout 控件时,代码中有趣的部分就会被执行。我选择了窗体的 OnMouseDown 事件来保持鼠标点击的位置:

// 另外两个单选按钮有类似于这个的 OnChange 事件处理程序,将值 TEdit 或 TButton 分配给 FControlType 字段。一个类似的赋值也出现在表单的 OnCreate 事件处理程序中,用作初始化方法。代码的有趣部分是在用户点击覆盖整个表单表面的 TLayout 控件时执行的。我选择使用表单的 OnMouseDown 事件来保存鼠标点击的位置:
procedure TForm1.Layout1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
var
   NewCtrl: TControl;
   NewName: string;
begin
   // 创建控件
   NewCtrl := FControlType.Create(Self);
   // 暂时隐藏它,以避免闪烁
   NewCtrl.Visible := False;
   // 设置父级和位置
   NewCtrl.Parent := Layout1;
   NewCtrl.Position.X := X;
   NewCtrl.Position.Y := Y;
   // 计算唯一的名称(和文本)
   Inc(FControlNo);
   NewName := FControlType.ClassName + FControlNo.ToString; 
   Delete(NewName, 1, 1);
   NewCtrl.Name := NewName;
   // 现在显示它
   NewCtrl.Visible := True;
end;

​ 该方法的第一行代码是关键。它将创建一个存储在 FControlType 字段中的类数据类型的新对象。我们只需将 Create 构造函数应用于类引用即可实现这一目的。

​ 现在,您可以设置父属性的值、设置新组件的位置、为其命名(名字会自动用作文本)并使其可见。

​ 请特别注意用来创建名称的代码:为了模仿 Object Pascal 的默认命名约定,我通过表达式 FControlType.ClassName 获取了类的名称,这是TObject 类的类方法。然后,我在名称末尾添加了一个数字,并删除了字符串的首字母。

​ 对于第一个单选按钮,假设 FControlNo 是 1,那么 FControlType 就是 TRadioButton;因此,FControlType.ClassName 返回字符串 “TRadioButton”,FControlNo.AsString 返回 “1”,我们在复制字符串减去第一个字符(即减去字符串开头的 “T”)之前将 "1 "追加到字符串末尾,从而得到新实例使用的最终字符串 “RadioButton1”。看起来熟悉吗?

图 12.1:在 Window 下运行 ClassRef 应用程序的输出示例

​ 图 12.1 是该程序的输出示例。请注意,该程序的命名与集成开发环境的命名并不完全相同,集成开发环境会为每种类型的控件使用单独的计数器。

​ 该程序对所有组件都使用一个计数器。因此,在运行 ClassRef 应用程序时,如果先放置一个按钮,然后是一个单选按钮,接着是两个编辑按钮,然后是另一个按钮,它们的名称将是 Button1、RadioButton2、Edit3、Edit4、Button5,如图所示。

​ 请注意,与设计器不同,创建的编辑控件名称不可见。

​ 顺便提一下,一旦创建了通用组件,就可以使用反射以非常动态的方式访问其属性,这在第 16 章中有详细介绍。在同一章中,我们将看到除了类引用外,还有其他方法来引用类型和类信息。

  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值