Delphi - проблема со ссылками на объекты, созданные во время выполнения

Я использую Delphi 7. Я написал некоторый код для создания кнопок во время выполнения (мне нужно много одинаковых кнопок в одинаковых местах в каждой форме, поэтому я решил это сделать). Но у меня возникают проблемы со ссылками на них в процедурах (если быть точным, на OnClick). Я хочу, чтобы другая форма открывалась при нажатии кнопки.

unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, jpeg, ExtCtrls;

procedure buttons(a: TForm);

type
 TForm2 = class(TForm)
  Image1: TImage;
  procedure FormShow(Sender: TObject);
  procedure Button1Click(Sender: TObject);
  procedure Button2Click(Sender: TObject);
  private
   { Private declarations }
  public
   { Public declarations }
end;

var
 Form2: TForm2; Button1, Button2, Button3, Button4: TButton;

implementation

uses Unit3, Unit4;

{$R *.dfm}

procedure buttons(a: TForm);
 begin
  Button1 := TButton.Create(a);
  Button1.Name := 'Button1';
  Button1.Left := 712;
  Button1.Top := 96;
  Button1.Width := 81;
  Button1.Height := 41;
  Button1.Visible := True;
  Button1.Parent := a;
  Button1.Enabled := False;
  Button1.Caption := 'Go forwards';
  Button2 := TButton.Create(a);
  Button2.Name := 'Button2';
  Button2.Left := 800;
  Button2.Top := 152;
  Button2.Width := 81;
  Button2.Height := 41;
  Button2.Visible := True;
  Button2.Parent := a;
  Button2.Enabled := False;
  Button2.Caption := 'Go right';
  Button3 := TButton.Create(a);
  Button3.Name := 'Button3';
  Button3.Left := 624;
  Button3.Top := 152;
  Button3.Width := 81;
  Button3.Height := 41;
  Button3.Visible := True;
  Button3.Parent := a;
  Button3.Enabled := False;
  Button3.Caption := 'Go left';
  Button4 := TButton.Create(a);
  Button4.Name := 'Button4';
  Button4.Left := 712;
  Button4.Top := 208;
  Button4.Width := 81;
  Button4.Height := 41;
  Button4.Visible := True;
  Button4.Parent := a;
  Button4.Enabled := False;
  Button4.Caption := 'Go back';
 end;


procedure TForm2.FormShow(Sender: TObject);
 begin
  buttons(Form2);
  Button1.Enabled := True;
  Button2.Enabled := True;
 end;

procedure TForm2.Button1Click(Sender: TObject);
 begin
  Form3.Show;
  Form2.Hide;
 end;

procedure TForm2.Button2Click(Sender: TObject);
 begin
  Form4.Show;
  Form2.Hide;
 end;

end.

Я также объявил OnClicks в 'type', как я, вероятно, должен. Программа запускается, но созданные кнопки не работают, хотя и кликабельны. Идеи?

PS: я знаю, что мог бы написать более компактный код для создания всех этих кнопок, но у меня не было времени подумать об этом, и это в значительной степени не относится к делу. Я знаю, что это может быть трудно читать - все, что вам нужно знать, это то, что я устанавливаю одинаковые свойства для каждой кнопки - вам нужно только смотреть на Button1, остальные идентичны.

PPS: НЕ двойной вопрос к этому: Delphi - Ссылки на компоненты, созданные во время выполнения. Я не мог найти решение своей проблемы в этом.

2 ответа

Решение

Прежде всего вы должны немного очистить свой код. Но это не то, почему ваш код не работает. Это потому, что вы забыли назначить событие OnClick для вашей кнопки:

Посмотри на это:

unit Unit19;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm19 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    Button1: TButton;
    Button2: TButton;
    Procedure CreateButtons;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form19: TForm19;

implementation

{$R *.dfm}

procedure TForm19.Button1Click(Sender: TObject);
begin
  Caption := 'Button1 Clicked';
end;

procedure TForm19.Button2Click(Sender: TObject);
begin
  Caption := 'Button2 Clicked';
end;

procedure TForm19.CreateButtons;
begin
  Button1 := TButton.Create(Self);
  Button1.Name := 'Button1';
  Button1.Left := 712;
  Button1.Top := 96;
  Button1.Width := 81;
  Button1.Height := 41;
  Button1.Visible := True;
  Button1.Parent := Self;
  Button1.Enabled := False;
  Button1.OnClick := Button1Click;

  Button1.Caption := 'Go forwards';
  Button2 := TButton.Create(Self);
  Button2.Name := 'Button2';
  Button2.Left := 800;
  Button2.Top := 152;
  Button2.Width := 81;
  Button2.Height := 41;
  Button2.Visible := True;
  Button2.Parent := Self;
  Button2.Enabled := False;
  Button2.Caption := 'Go right';
  Button2.OnClick := Button2Click;
end;

procedure TForm19.FormCreate(Sender: TObject);
begin
  CreateButtons;
end;

end.

Сначала очистка: я переместил объявление вашей кнопки в приватную часть формы, которой они принадлежат.

О владельце кнопки, параметре конструктора; Это должна быть форма. Потому что, когда вы уничтожаете форму, это также уничтожит ваши кнопки, и не будет утечки памяти.

Тогда пропавший OnClick событие, которое решается с помощью этой строки:

Button1.OnClick := Button1Click;

Я просто говорю кнопке, какую процедуру вызывать, когда пользователь нажимает кнопку.

Я надеюсь, что это отвечает на ваш вопрос.

В вашей ситуации я бы использовал Frames. Вы можете разместить все кнопки в этом кадре, вы можете изменить поведение, используя свойства, назначить все необходимые события и поместить его в форму во время разработки или во время выполнения.

Другие вопросы по тегам