Dynamiczne komponenty i funkcje Borland C++

0

Witam!

Proszę o pomoc w rozwiązaniu następującego problemu:

  1. Definiuję sobie wskaźnik na tablicę wskaźników komponentów TRadioButton:
TRadioButton **tabodp;
  1. Podczas działania programu tworzę tablicę wskaźników na komponenty TRadioButton, której rozmiar jest dynamiczny i zależy od zmiennej ileodp, której wartość powstaje w trakcie działania programu:
tabodp = new TRadioButton*[ileodp];
  1. W pętli wyświetlam wszystkie komponenty (l,t,k - zmienne pomocnicze, atrtab - tablica obiektów, get_atrciag() - metoda klasy):
for(k=0;k<ileodp;k++)
     {
         t+=30;
         tabodp[k]=new TRadioButton(this);
         tabodp[k]->Parent=this;
         tabodp[k]->Left=l;
         tabodp[k]->Top=t;
         tabodp[k]->Caption = atrtab[k]->get_atrciag();
     }
  1. Tworzę dynamiczne zdarzenie dla komponentu TRadioButton:
projekt.h

private:
        void __fastcall klik(TObject *Sender);	// User declarations

projekt.cpp

void __fastcall TForm1::klik(TObject *Sender)
{
    ... // pewne instrukcje po wywolaniu zdarzenia klik
}

  1. Do tej pory wszystko jest dla mnie zrozumiałe :)
    Problem pojawia się w poniższym fragmencie, gdy chcę się odwołać do dynamicznego zdarzenia:

for(k=0;k<ileodp;k++)
   tabodp[k]->OnClick=klik;

Zdarzenie klik będzie wykonywało w każdym przypadku bardzo podobną rolę, tylko że potrzebuję wiedzieć, na którym k zostało wywołane, tzn. który komponent został kliknięty.
Ponieważ ilość komponentów, w trakcie trwania programu, ulega dynamicznej zmianie, więc nie mogę na sztywno zdefiniować żadnych zdarzeń, bo nie wiem, ile będzie komponentów.
Wykombinowałem zatem sposób, w którym jedno zdarzenie może obsłużyć wszystkie komponenty (zdarzenie klik), tylko że w tym zdarzeniu ważne jest, żeby wiedzieć, który komponent został kliknięty (przy którym k nastąpiło wywołanie zdarzenia OnClick).

  1. Wiem, że podczas definiowania zdarzenia dynamicznego nie wolno go przeciążać (w zasadzie to nie wiem, czy w ogóle wolno przeciążać zdarzenie), dlatego nie mogę dorzucić sobie zmiennej k jako argumentu zdarzenia.

  2. Jednym zdaniem pisząc - skąd będę wiedział, który komponent został kliknięty? Są tworzone dynamicznie, więc nie mogę określić z góry ani ich liczby, ani ich właściwości, natomiast k jest mi potrzebne, bo będzie przekazane do tablicy atrtab i tam będą wykonywane dalsze czynności.

Dziękuję z góry za wszelkie pomysły i pozdrawiam!

0
for(k=0;k<ileodp;k++)
     {
         //...
         //dopisz do buttona jego identyfikator (liczbe k), mozna ja przechowac w Tag
         tabodp[k]->Tag = k;         
     }

void __fastcall TForm1::klik(TObject *Sender)
{
    //Sender to twoj button
   TRadioButton *Button = (TRadioButton*) Sender;

   //a jego identyfikator to
   int k = Button->Tag;
}
0

Super - dokładnie o to mi chodziło :D

Mam jeszcze do Ciebie jedną prośbę:

TRadioButton *Button = (TRadioButton*) Sender;

Wytłumacz mi, proszę tę linijkę, a dokładniej, to skąd ją wytrzasnąłeś :)

0

Jak pisałem, w parametrze Sender przekazywany jest wskaźnik na obiekt, który wywołał zdarzenie. Potrzebne jest tylko rzutowanie na typ TRadioButton aby dobrać się do własności Tag. U ciebie Sender będzie zawsze TRadioButton'em, ale normalnie może to być dowolny obiekt. Tą samą procedurę OnClick można przypisać różnym obiektom, nie koniecznie tego samego typu, np. panelowi i przyciskowi. Wtedy jeśli zdarzenie wywoła panel to Sender'em będzie TPanel, jak button to TButton. Wspólne dla nich jest to, że każdy jest TObject'em i dlatego takiego typu jest Sender.

0

Dzięki wielkie, wszystko jasne :)
Temat do zamknięcia.
Pozdrawiam!

0

Ja właśnie trafiłem na podobny problem, wiedziałem, że sender będzie do tego potrzebny ale na rzutowanie bym nie wpadł :D wielkie dzięki za pomoc.

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