在Delphi上如何引用仅使用一个变量创建的对象?

问题描述 投票:2回答:1

我在我的应用程序中运行时创建了一个带有一些按钮的表单,我意识到一些困扰我的东西,我无法想象自己或互联网上的任何地方。

请查看以下代码。

procedure TfrmTest.CreateFourButtons(Sender: TObject);
var
  i: Integer; B: TButton;
begin
  for i := 1 to 4 do
    begin
      B := TButton.Create(frmTest);
      B.Parent := frmTest;
      B.SetBounds(250,(70+(30*i)),75,25);
      B.Caption := 'Button' + IntToStr(i);
      B.Visible := True;
    end;
end;

所以我只是在运行时在特定位置的表单上创建了四个按钮。到目前为止这么好吧?

但现在让我们想象一下,我想将第一个按钮的Caption属性更改为“HotPotato”?我现在如何引用第一个按钮,因为我只使用一个变量来创建这些按钮?我被告知要将这些对象存储在TButton数组中,或者更好地存储在TObjectList中,这些都是解决这个问题的好方法。但后来我想到了一个问题!

这些按钮位于内存中的哪个位置?我是否可以在不使用数组或对象列表的情况下引用它们?

object delphi memory-management
1个回答
3
投票

跟踪多个类似对象的常规方法是使用数组。

procedure TfrmTest.CreateFourButtons(Sender: TObject);
var
  i: Integer; 
  B: TArray<TButton>; //or array of TButton for older versions
begin
  SetLength(B, 4);
  for i := 0 to 3 do begin
    B[i] := TButton.Create(frmTest);
    B[i].Parent := frmTest;
    B[i].SetBounds(250,(70+(30*i)),75,25);
    B[i].Caption := 'Button' + IntToStr(i);
    B[i].Visible := True;
  end;
  B[0].Caption:= 'HotPotato';
end;

当在表单上放置按钮时,这不是严格需要的,表单已经使用列表来跟踪放置在其上的子控件,但是您需要某种方式来区分不同的按钮。

您可以使用tag属性:

  for i := 1 to 4 do begin
    B := TButton.Create(frmTest);
    B.Parent := frmTest;
    B.Tag:= i;
    ...
  end;
  //This will get inefficient if there are many controls on a form.
  for var C in frmTest.Controls do begin  //10.3 syntax.
    if (C is TButton) and (C.tag = 1) then C.Caption:= 'HotPotato'
  end;

button是一个对象,因此它位于堆上。如果你失去了它的参考,你将再也找不到它。但是,如果它被放置在父控件上,那么该父控件将跟踪它,并且您始终可以使用FindChildControl或表单的Controls列表来获取它。

FindChildControl按名称搜索。这需要您设置控件的名称,否则它将不起作用。

var B:= frmTest.FindChildControl('Button1');

注意:FindChildControl仅定位控件的直接子项。它无法找到控件的一个控件的子控件。

如果按钮位于子面板中,则定位儿童可能会变得复杂。最好使用数组或列表来跟踪一系列按钮。

© www.soinside.com 2019 - 2024. All rights reserved.