Event do dynamicznego Buttona

0

witam wszystkich, jestem początkujący i mam następujący problem:
gdy po przeczytaniu artykułu Dynamika utworzę buttona nie mogę dodać do niego zdarzenia oto kod:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    procedure BitBtn2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  var buttony : array of TButton; //Jako zmienna globalna

implementation

{$R *.DFM}

procedure Procedura_typu_onClick;
begin
ShowMessage('Co mnie klikasz :>');
Buttony[0].visible:=false;
// I tym podobne //

end;


procedure TForm1.BitBtn2Click(Sender: TObject);
begin
SetLength(Buttony,Length(buttony)+1); //Zmienia wielkość tablicy buttonów o jeden

//Ach wreszcie tworzymy to co trzeba :)

Buttony[1] := TButton.Create(Self {np Form1,Panel1 itp}) ;
Buttony[1].Parent := Self {np Form1,Panel1 itp};
Buttony[1].Caption := 'Dynamika RLZ';
Buttony[1].Top     := 50;
Buttony[1].Left    := 50;
Buttony[1].Visible := true;
Buttony[1].Width   := 75;
Buttony[1].Height  := 25;
// A teraz zdarzenia do tego: //
Buttony[1].OnClick := Procedura_typu_onClick; //napisana wcześniej :)
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Buttony[1].free;
SetLength(buttony,Length(buttony)-1); //Zmienia wielkość tablicy buttonów o jeden
end;

co jest źle?

0

czy proedura_typu_onclick =
procedure click(Sender:TObject); tak powinno bbyc. sprobuj jeszcze zrobic TForm1.klikSender:TObject); i to przypisac;

robilem tak nie raz i dzialalo.

0

dziękuje postaram się

0

Nie działa, bo procedury obsługi zdarzeń muszą być metodami obiektów. Spróbuj wstawić nagłówek tej procedury do deklaracji klasy TForm, a później zaimplementować w znany sposób :)

0

W zasadzie n_a_v_ podał już odpowiedź...

Tworzysz dynamicznie buttona - czym on się różni od zwykłego buttona - ano niczym, oprócz tego, że nie istnieje od początku "formy rodzica". Ale tak poza tym nie ma żadnych różnic między buttonem dynamicznym i zwykłym. Więc nagłówek każdego zdarzenia musi być taki sam jak jest zdeklarowany w klasie TButton - gdyż Ty nie deklarujesz własnej klasy - tworzysz tylko dynamicznie obiekt danej klasy. Nagłówek Twojej metody nie jest taki sam jak nagłówek metody "OnClick" klasy TButton.

Zmień nagłówek swojej procedury_typu_click na:

procedure TForm1.procedura_typu_click(Sender: TObject);

i oczywiście deklaracja (nagłówek) tej procedury powinna się znaleźć w sekcji private lub public

0

BTW - masz tu błąd:

Buttony[1].free;
SetLength(buttony,Length(buttony)-1);

zwalniasz pierwsze pole tablicy, a z samej tablicy usuwasz ostatnie. musisz jeszcze przesunąć dane o jedno pole.

0

chyba udało mi się
może komuś się przyda:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    Label1: TLabel;
    procedure BitBtn2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure typu_onClick (Sender: TObject);
  end;

var
  Form1: TForm1;
  var Buttony : array of TButton; //Jako zmienna globalna
      i     : Integer;
implementation

{$R *.DFM}

procedure TForm1.typu_onClick(Sender: TObject);
begin
ShowMessage('Co mnie klikasz :>');
Buttony[I-1].visible := false;
Label1.Caption := IntToStr(Length(Buttony));
// I tym podobne
end;


procedure TForm1.BitBtn2Click(Sender: TObject);
begin
SetLength(buttony,Length(Buttony)+1); //Zmienia wielkość tablicy buttonów o jeden

//Ach wreszcie tworzymy to co trzeba :)

Buttony[I]         := TButton.Create(Self {np Form1,Panel1 itp}) ;
Buttony[I].Parent  := Self {np Form1,Panel1 itp};
Buttony[I].Caption := 'Dynamika RLZ';
Buttony[I].Top     := 50;
Buttony[I].Left    := 50+I*50; // kolejne buttony będą się "przesuwały" 
Buttony[I].Visible := true;
Buttony[I].Width   := 75;
Buttony[I].Height  := 25;
// A teraz zdarzenia do tego:
Buttony[I].OnClick := typu_onClick; //napisana wcześniej :)
I := I+1;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var J : Integer;
begin
 //Buttony := nil;             // to zwalnia całą tablicę Buttonów

 if Buttony <> nil then   // istnieje możliwość że nie zostnie utworzony dynamiczny button
   for J := I-1 downto 0 do    { a to zwalnia button po buttonie, można wykożystać do
                        zwalniania pojedyńczego buttona, lecz należy uwzględnić uwagę ŁF }
     begin
     Buttony[J].free;
     SetLength(buttony,Length(buttony)-1); //Zmienia wielkość tablicy buttonów o jeden
     end;
 // u mnie gdy stosowałem jeden jak i drugi sposób nie powoduje teraz błędu,
 // we wcześniejszej wersji zmiana indeksu na 0 zlikwidowało błąd generowany przy wyjściu z programu

end;

procedure TForm1.FormActivate(Sender: TObject);
begin
Label1.Caption := IntToStr(Length(Buttony));
I := 0;
end;

end.

dziękuję za pomoc, pozdrowienia

0

czy tobie to dziala poprawnie?? bo moim zdaniem to jest porypane. Np. Dodajesz 2 buttony, klikasz na 2 i dodajesz nastepne. I Jest DZIURA!!

0

tak zauważ na początku ustawia I na 0 bodaje buttona , pokazuję go i zmieniam I na 1 następnie chowam (jeżeli ktoś przyciśnie go), na koniec zwalniam buttony pamiętając o tym że ilość buttonów I jest zawsze jest zawyżona o jeden

faktycznie błąd, chowa tylko ostatniego buttona, zamieniamy

Buttony[I-1].visible := false;

na

(Sender as TButton).Visible := false;

i wszysko gra...

1 użytkowników online, w tym zalogowanych: 0, gości: 1