我是 delphi 和 pascal 的新手,想知道是否有办法获取/访问发送者在过程中引用的组件的属性。
更具体地说,我想制作一个更改标签的标题属性的过程,该标签是Sender引用的组件。我想象这个过程看起来像:
procedure TForm1.LabelEdit(Sender: TObject);
begin
Sender.caption := 'Sample Text';
end;
Run Code Online (Sandbox Code Playgroud)
自然这行不通,但可以做类似或类似的事情吗?
尽管您问题中的示例没有真正意义(它错误地表明 aTLabel具有OnEdit事件),但很有可能使用该Sender参数来获取有关发件人对象的信息。
创建一个新的 VCL 应用程序并TLabel在窗体上放置一些控件。给他们不同的标题(如Dog,Cat,Rabbit,Horse等)。
现在在表单设计器中选择它们,然后使用Object InspectorOnClick为它们创建一个公共处理程序。您可以为其命名LabelClick(LabelClick在旁边的编辑字段中写下OnClick并按Enter)。
这将创建以下空方法:
procedure TForm1.LabelClick(Sender: TObject);
begin
end;
Run Code Online (Sandbox Code Playgroud)
它有一个Sender类型的参数TObject。现在,根据调用此方法的方式,Sender可以是任何TObject(按钮、表单、位图等)或nil(根本没有对象)。
但是在我们的例子中,我们希望这个方法主要是在响应标签被点击时被调用,在这些情况下,Sender将是相应的TLabel对象。
让我们尝试在消息框中显示单击标签的标题!
我们试着
procedure TForm1.LabelClick(Sender: TObject);
begin
ShowMessage(Sender.Caption); // won't compile!
end;
Run Code Online (Sandbox Code Playgroud)
但这甚至无法编译!问题是TObject没有公共Caption成员。但是TLabel确实如此,所以我们可以写
procedure TForm1.LabelClick(Sender: TObject);
begin
ShowMessage(TLabel(Sender).Caption);
end;
Run Code Online (Sandbox Code Playgroud)
在这里,我们告诉编译器我们知道 Sender永远是 a TLabel,并且我们要求它假设它是。
但是,如果以某种方式使用非TLabel Sender. 所以这样做更安全
procedure TForm1.LabelClick(Sender: TObject);
begin
ShowMessage((Sender as TLabel).Caption);
end;
Run Code Online (Sandbox Code Playgroud)
除了编译器现在将创建在运行时检查Sender确实是TLabel对象的代码之外,这也是一样的。如果没有,代码将引发异常。这比使用上面的不安全转换可能会遇到的内存损坏/AV 问题要好得多。
可以说更好的是
procedure TForm1.LabelClick(Sender: TObject);
begin
if Sender is TLabel then
ShowMessage(TLabel(Sender).Caption);
end;
Run Code Online (Sandbox Code Playgroud)
这也将Sender在运行时测试 的类型。如果它是一个标签,我们会显示它的标题。否则,我们选择什么都不做。请注意,在这里使用安全的(稍微、稍微、慢一点)as强制转换是没有意义的。