如何动态添加控件到Delphi窗体中

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

我正在尝试向应用程序动态添加按钮控件。我正在开发的应用程序有多达 6 个不同的预定义按钮位置,它们可以是几种不同操作中的任何一种。例如,如果用户按下“新建”按钮,我想动态显示“保存”、“清除”和“取消”按钮,并使每个

OnClick
事件指向正确的过程/函数。每个按钮都在
TButton
数组中定义,并根据需要分配给表单上的预定义按钮。

这是我构建的示例程序,旨在帮助理解我想要实现的目标:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    btnPos1: TButton;
    procedure btnNewClick(Sender: TObject);
    procedure Form1Close(Sender: TObject; var Action: TCloseAction);
    procedure Form1Create(Sender: TObject);
  private
    { Private declarations }
  public
    procedure LoadButtons;
  end;

var
    Form1: TForm1;
    FormBtns: array[1..20] of TButton;

implementation

{$R *.dfm}

procedure TForm1.LoadButtons;
begin
    FormBtns[1].Caption:='&New';
    FormBtns[1].OnClick:=btnNewClick;
    FormBtns[1].Left:=340;
    FormBtns[1].Top:=20;

    btnPos1.Caption:=FormBtns[1].Caption;
    btnPos1.OnClick:=FormBtns[1].OnClick;
    btnPos1.Left:=FormBtns[1].Left;
    btnPos1.Top:=FormBtns[1].Top;
end;

procedure TForm1.btnNewClick(Sender: TObject);
begin
    // do something
end;

procedure TForm1.Form1Close(Sender: TObject; var Action: TCloseAction);
begin
    Application.Terminate();
end;

procedure TForm1.Form1Create(Sender: TObject);
begin
    LoadButtons;
end;

end.    

当此测试和实际应用程序运行时,我收到以下错误:

Project BtnTest.exe raised exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'.

它发生在以下代码上:

    FormBtns[1].OnClick:=btnNewClick;

我假设由于某种原因它无法协调

btnNewClick
参考,但我不明白为什么。我什至不确定这是否是完成工作的最佳方式。任何帮助将不胜感激。谢谢。

delphi
1个回答
0
投票

您已经声明了一个不指向任何内容的

TButton
pointers 数组。您必须先实际创建
TButton
对象,然后才能访问它们的属性,例如:

procedure TForm1.LoadButtons;
begin
  FormBtns[1] := TButton.Create(Self);
  FormBtns[1].Parent := Self;
  ...
end;

而且你根本不需要

btnPos1
,所以摆脱它。

FormBtns
也应该是
TForm1
类的成员,而不是全局变量。

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