简体   繁体   English

Delphi-麻烦引用在运行时创建的对象

[英]Delphi - trouble referencing objects created at runtime

I'm using Delphi 7. I've written some code to create buttons at runtime (I need lots of the exact same buttons in the exact same locations on every form, which is why I've decided to do that). 我使用的是Delphi7。我已经编写了一些代码在运行时创建按钮(我需要在每个表单的完全相同的位置上放置许多完全相同的按钮,这就是我决定这样做的原因)。 But I'm having trouble referencing them in procedures (OnClick, to be precise). 但是我在过程(准确地说是OnClick)中引用它们时遇到了麻烦。 I want another form to open when a button is clicked. 我希望在单击按钮时打开另一个表单。

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.

I've declared the OnClicks in 'type', as well, as I probably should. 我也已经将OnClicks声明为“类型”。 The program runs, but the created buttons don't work, though are clickable. 该程序会运行,但是创建的按钮无法工作,尽管可以单击。 Ideas? 有想法吗?

PS: I know I could've written more compact code to create all those buttons, but I didn't have time to think about it, and it is pretty much beside the point. PS:我知道我可以编写更紧凑的代码来创建所有这些按钮,但是我没有时间考虑它,这很重要。 I know it might be hard to read - all you need to know is, I set the same kinds of properties on every button - you need only look at Button1, the others are identical. 我知道可能很难读-您需要知道的是,我在每个按钮上设置了相同类型的属性-您只需要看一下Button1,其他都一样。

PPS: NOT a dup question to this: Delphi - Referencing Components created at Runtime . PPS:这不是一个重复的问题: Delphi-引用在运行时创建的组件 I couldn't find a solution to my problem in that one. 在那个问题上,我找不到解决方案。

First of all you should clean up your code a bit. 首先,您应该清理一下代码。 But it's not why your code isn't working. 但这不是为什么您的代码无法正常工作的原因。 It's because you forgot to assign an OnClick Event to your button: 这是因为您忘记为按钮分配OnClick事件:

Have a look at this : 看看这个:

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.

First the cleanup: I've moved the declaration of your button up to the private part of the form that owns them. 首先清理:我已经将您按钮的声明移到了拥有它们的表单的私有部分。

About the owner of the button, the parameter of the constructor; 关于按钮的所有者,构造函数的参数; It must be the form. 它必须是表格。 Because when you destroy the form it will also destroy your buttons, and no memory will be leaked. 因为当您销毁表格时,它也会销毁您的按钮,并且不会泄漏任何内存。

Then the missing OnClick event that is solved with this line: 然后,用此行解决的缺少的OnClick事件:

Button1.OnClick := Button1Click;

I simply tell the button which procedure to be called when the user click the button. 我只是简单地告诉按钮,当用户单击按钮时要调用哪个过程。

I hope this answers you question. 我希望这能回答您的问题。

In your situation I would use Frames. 在您的情况下,我会使用框架。 You can place all buttons on this frame, you can change the behavior by using properties, assign all needed events and put it on your form at design time or at run time 您可以将所有按钮放在此框架上,可以通过使用属性来更改行为,分配所有需要的事件,然后在设计时或运行时将其放在表单上

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM