Newsgroup: it.comp.lang.c++
Titolo: Matrici di oggetti VCL

Salve a tutti,
vorrei sapere come posso creare in BCBuilder degli array di componenti
(ad esempio CheckBox) che in visual basic riesco a fare cosi'
facilmente?
Un ringraziamento a tutti coloro mi sanno postare la risposta.
PPL


Con BCB non si possono creare arrays di componenti direttamente da IDE, come in
Visual Basic. Se l'obbiettivo č semplicemente quello di creare una serie di
controlli che condividono dei gestori di eventi, non c'č bisogno di creare
nessun array, basta assegnare la stessa funzione allo stesso evento per ogni
componente del gruppo, poi gestire opportunamente l'evento a seconda del
controllo selezionato.
L'esempio che segue si riferisce a un gruppo di CheckBox che
attivano/disattivano i diversi flags di un Set. I tre CheckBox sono stati creati
da IDE, e sull'Object Inspector č stata assegnata loro, come gestore dell'evento
Click, la stessa funzione ckbOptionsClick. Ciascun CheckBox agisce su un diverso
flag del Set FOptions.
enum TMyOptionsFlag { optOne, optTwo, optThree };
typedef Set<TMyOptionsFlag, optOne, optThree> TMyOptions;
class TMyForm : public TForm
{
.................
    TCheckBox* ckbOptionOne;
    TCheckBox* ckbOptionTwo;
    TCheckBox* ckbOptionThree;
.................
    TMyOptions FOptions;
.................
    void __fastcall FormCreate(TObject *Sender);
.................
    void __fastcall ckbOptionsClick(TObject *Sender);
.................
};
void __fastcall TMyForm::FormCreate(TObject *Sender)
{
    ckbOptionOne->Tag = static_cast<int>(optOne);    
    ckbOptionOne->Tag = static_cast<int>(optTwo);    
    ckbOptionOne->Tag = static_cast<int>(optThree);    
}
void __fastcall TMyForm::ckbOptionsClick(TObject *Sender)
{
    TCheckBox* ckb = static_cast<TCheckBox*>(Sender);
    TMyOptionsFlag flag = static_cast<TMyOptionsFlag>(ckb->Tag);
    if (ckb->Checked)
        FOptions << flag;
    else    
        FOptions >> flag;
}
In altri casi in cui l'uso della proprietą Tag non fosse appropriato, si
potrebbe usare una serie di if ... else if:
class TMyForm : public TForm
{
.................
    TCheckBox* ckbOne;
    TCheckBox* ckbTwo;
    TCheckBox* ckbThree;
.................
    void __fastcall CheckBoxClick(TObject *Sender);
.................
    void DoSomething(bool Value);
    void DoSomethingElse(bool Value);
    void DoAnotherThing(bool Value);
.................
};
void __fastcall TMyForm::CheckBoxClick(TObject *Sender)
{
    TCheckBox* ckb = static_cast<TCheckBox*>(Sender);
    bool value = ckb->Checked;
    if (ckb == ckbOne)
    {
        DoSomething(value);
    }
    else if (ckb == ckbTwo)
    {  
        DoSomething(value);
        DoSomethingElse(value);
    }
    else if (ckb == ckbThree)
    {
        DoAnotherThing(value);
        DoSomethingElse(value);
    }
}
 
E' necessario definire un vero e proprio array solo se si vuole avere la
possibilitą di gestire i diversi controlli come un insieme, all'interno di un
ciclo. In questo caso aggiungo un membro alla classe (nel file header), che
potrebbe essere un semplice array di puntatori o una istanza della classe STL
vector o ancora un altro contenitore. L'esempio seguente usa un semplice array:
class TMyForm : public TForm
{
.................
    TCheckBox* ckbOne;
    TCheckBox* ckbTwo;
    TCheckBox* ckbThree;
.................
    TCheckBox* FCheckBoxes[3];
.................
    void __fastcall FormCreate(TObject *Sender);
.................
    void CheckAllBoxes(bool Value);
.................
};
poi lo inizializzo:
void __fastcall TMyForm::FormCreate(TObject *Sender)
{
    FCheckBoxes[0] = ckbOne;    
    FCheckBoxes[1] = ckbTwo;    
    FCheckBoxes[2] = ckbThree;    
}
e poi uso l'array in un ciclo:
void TMyForm::CheckAllBoxes(bool Value)
{
    for (int i = 0; i < 3; i++)
        FCheckBoxes[i]->Checked = Value;
}
-----------------------
Saluti
Paolo