2015-05-03 56 views
1

我正在使用德尔福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. 

我已经在'type'中声明了OnClicks,因为我可能应该这样做。该程序运行,但创建的按钮不起作用,但可点击。想法?

P.S .:我知道我可以编写更简洁的代码来创建所有这些按钮,但我没有时间思考它,而且这非常重要。我知道这可能很难阅读 - 所有你需要知道的是,我在每个按钮上设置了相同的属性 - 你只需要看Button1,其他的都是一样的。

P.P.S .:不是这个dup问题:Delphi - Referencing Components created at Runtime。我找不到解决我那个问题的方法。

+0

'Button1:= TButton.Create(Button1);'应该读取'Button1:= TButton.Create(a);'。 –

+0

谢谢,它应该。它没有改变,但 - 按钮仍然不起作用。 – Valikojan

回答

6

首先你应该清理一下你的代码。但这不是你的代码无法工作的原因。这是因为你忘了分配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; 

我简单的告诉哪个程序,当用户点击该按钮被称为按钮。

我希望这能回答你的问题。

+0

谢谢,它差不多。正如你所建议的那样,我已经在'private'中声明了这些按钮,并将ButtonClick声明移到了'private'中;尽管(在“使用”和“类型”之间)保留了按钮创建过程的声明,因为我希望其他单位能够使用它;我还添加了您提到的行,以指定单击时要调用的过程。但是,Delphi现在说'Button1Click'是一个未声明的标识符(除非我在var中声明按钮,否则它也会为'Button1'所做的)。我认为这是因为我的程序依赖于TForm变量(即'a')? – Valikojan

+0

把声明和你的按钮放到窗体的公共部分,它会破坏 –

+1

@Jens这里有很多拼写错误。请你重新阅读并纠正。好的答案,通过拼写略微损坏。 –

2

在你的情况我会使用框架。您可以将所有按钮放置在该框架上,您可以通过使用属性来改变行为,分配所有需要的事件,并在设计时或在运行时将其放置在窗体上

+0

但这并不能解决丢失Click事件的问题 –

+0

是和否,但是您可以像在普通窗体上那样对点击事件进行“硬编码”。但其根本原因仍然存在:当您希望点击产生反应时,您必须通过点击编程反应 –

+0

@JensBorrisholt实际上,使用此解决方案将解决缺少OnClick事件的问题。为什么?在设计框架内容时,如同他现在在第二张表格上所做的那样,让OP在设计时指派他们。现在,尽管您的方法更适合在运行时创建组件的场景(它们的创建可以根据特定参数进行变化),但Christine答案更适合于组件行为在设计时被设计但仅需要在多个表单上复制运行。所以我提出了两个答案。 – SilverWarior