2015-05-03 50 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