Newsgroup: it.comp.programmare.win32
Titolo: [C++ builder] componenti a run-time

Salve,
è possibile generare a run-time una TLabel ad esempio senza doverla mettere
manualmente sulla form a design-time?
Grazie

manualmente sulla form a design-time?
Ovviamente sì. Assicurati di assegnarle la Form sia come owner (è
l'argomento che passi al costruttore) sia come parent (proprietà
Parent). L'owner determina la distruzione dell'oggetto, il parent la
visualizzazione.

 visualizzazione.
Indendi qualcosa tipo:
TLabel* t = new TLabe1(Form1);
t->Parent = Form1;
Puoi farmi un'esempio di codice funzionante?
Ciao 

t->Parent = Form1;
Esatto. Ovviamente devi fare sempre a meno di usare variabili globali
come Form1. Usa piuttosto Self.

 come Form1. Usa piuttosto Self.
Ok, ma puoi farmi un'esempio funzionante perché non so quale sintassi 
precisa usare:
ho provato:
TLabel* t = new TLabel(Self);
t->Parent = Self;
Ma non trova nessun Self... forse devo includere qualche libreria non so, ma 
ne questo ne l'esempio precedente compilano per questo ti chiedo un esempio 
funzionate :-)
Ciao 

 Ma non trova nessun Self...
In C++ è 'this', non 'Self'.
-- 
Stefano Frosio
www.esse-effe.com

 In C++ è 'this', non 'Self'.
Ah allora con self intedevi il this :)
Self mi pare si usi in Delphi e in Python.
Ho provato:
t = new TButton(this);
t->Parent = this;
t->Caption = "&CIAO";
t->Top = 50;
t->Left = 20;
Se adesso dovessi definire un'evento onClick come dovrei fare?
Grazie 

funzionate :-)
Ma non c'è granché da dire: una volta scritte quelle due righe sopra
assegni le varie proprietà esattamente come faresti da Object
Inspector. Se vuoi definire gli eventi, devi dichiarare nella tua form
un metodo che abbia la stessa firma dell'evento OnClick, definirlo
(i.e. scriverci dentro del codice9 e assegnarlo semplicemente alla
proprietà OnClick della nuova label.

 proprietà OnClick della nuova label.
Ho provato a definire questo:
void __fastcall tClick(TObject *Sender) {
    Form1->Label1->Caption = "Cliccato";
};
L'assegnazione come dovrebbe essere?
Ho provato:
t->OnClick = tClick
e mi da errore di compilazione:
[C++Error] Unit1.cpp(30): Cannot convert 'void (_fastcall *)(System::TObject 
*)' to 'void (_fastcall * (_closure )(System::TObject *))(System::TObject 
*)'.
però ho notato che invece un'istruzione come:
t->OnClick = Button2Click
la accetta.
Grazie 

*)'.
No, l'evento è una closure, devi definire il tuo tClick() come un
metodo della classe TForm1. Come già detto, non usare:
Form1->Label1->Caption = "Cliccato";
ma
this->Label1->Caption = "Cliccato";
Purtroppo Borland ha abituato i programmatori alla PESSIMA pratica di
far riferimento ad una sepcifica istanza di classe (Form1, Form2,
Form3, ... appunto) nel codice della classe stessa (TForm1, TForm2,
TForm3, ...). E' logicamente errato, perché se un domani tu volessi
istanziare più TForm2 (come è normale e frequente fare), avresti che
il codice della classe TForm2 si riferisce ad un'istanza specifica.
Si *DEVE* usare this dentro il codice di una classe e *MAI* il nome
dell'istanza specifica.

 metodo della classe TForm1.
Scusa se ti chiedo ancora informazioni ma ho provato così e non funziona:
void __fastcall TForm1::tClick(TObject *Sender) {
    this->Label1->Caption = "Cliccato";
};
Come faccio a definirlo dentro TForm1?
Grazie 

 Come faccio a definirlo dentro TForm1?
Ho inserito manualmente nell'header la dichiarazione:
void __fastcall tClick(TObject *Sender);
e ha funzionato, spero sia questa la prassi corretta :-)
Ciao 

 dell'istanza specifica.
Io ometto sempre la classe:
Label1->Caption = "Cliccato";
c'è qualche controindicazione?
Cristiano 

 c'č qualche controindicazione?
No, cosě va bene. L'importante č non far riferimento a quelle variabili.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 c'č qualche controindicazione?
Si anche io, ma il problema nasce quando ne fai uso all'interno di una 
funzione da te definita, dato che non č piů visibile.
Inoltre ho notato che se cancello la dichiarazione:
TForm1* Form1;
Ottengo questo errore di Linking:
[LinkerError] Unresolved external '_Form1' referenced from 
C:\PROGRAMMI\BORLAND\CBUILDER3\PROJECTS\PROJECT1.OBJ.
In un tuo post dicevi:
"Quel Form1 č dichiarato come variabile globale, subito dopo la
dichiarazione della classe TForm1. Non č che sia meglio cambiare nome,
devi cancellarla proprio."
Ma anche se non va usata e al suo posto bisogna ulitizzare this, non č 
possibile cancellarla?
Ciao 

possibile cancellarla?
E' possibile cancellarla.

 devi cancellarla proprio."
Replichi a me, ma forse ti riferivi ad Andrea. Io non credo di aver detto 
una cosa simile, tant'è che non la cancello mai.
Cristiano 

 E' possibile cancellarla.
Non so se ne avete già parlato, ma c'è un vantaggio nel cancellarla?
Cristiano 

Non so se ne avete già parlato, ma c'è un vantaggio nel cancellarla?
Sì, leggi il thread.

una cosa simile, tant'è che non la cancello mai.
E fai male, purtroppo.

 Fai un build.
Mi dice che ci sono degli errori e infatti se dopo provo a  compilare non 
funziona. 

funziona.
Quali errori?

 Quali errori?
Allora, creo un nuovo progetto, cancello quella dichiarazione di Form1, 
clicco su Project -> Build Project1 e ottengo questo:
http://www.geocities.com/noixe82/Errore.jpg
Uso C++ Builder 3
Ciao 

 
http://www.geocities.com/noixe82/Errore.jpg
E ci siamo. Ripeto: quale errore?


 E ci siamo. Ripeto: quale errore?
Sempre quello relativo al Linking di cui ti citavo. 

 C:\PROGRAMMI\BORLAND\CBUILDER3\PROJECTS\PROJECT1.OBJ.
Esattamente, purtroppo non ho notato che la form copriva il messaggio di 
errore nel momento in cui ho fatto lo screenshot. 

C:\PROGRAMMI\BORLAND\CBUILDER3\PROJECTS\PROJECT1.OBJ.
Hai tolto la creazione automatica di Form1 dal sorgente del progetto?
Non ho C++ Builder sotto mano, per cui non posso provare.
In ogni caso, eliminare quella variabile è ovviamente possibile.

 In ogni caso, eliminare quella variabile è ovviamente possibile.
Si, sono andato nella dichiarazione e l'ho cancellata. Non è questa la 
procedura corretta? 

procedura corretta? 
Non mi ricordo come funziona in C++ Builder, ma da qualche parte ci
deve essere la creazione dell'istanza di TForm1 e l'assegnazione a
Form1.

 Form1.
Non so, ho trovato solo la dichirazione che poi č quella che cancello 
ovvero:
TForm1* Form1;
Cmq non fa niente, puň anche restare dove č, il this posso usarlo ugualmente 
:)
Ciao 

:)
Sě, ma devi poterla cancellare. E' fattibile (ovviamente).

 No, l'evento è una closure, devi definire il tuo tClick() come un
Scusa l'ignoranza, ma... che significa "l'evento è una closure"? Cos'è
una closure?

 Sì, ma devi poterla cancellare. E' fattibile (ovviamente).
Ci sto pensando anch'io. "TForm1* Form1;" dichiara "un puntatore a" e
non "una istanza di" TForm1, per cui se c'è o non c'è, al compilatore
dovrebbe fregare poco. Forse Form1 viene usato poi all'interno della
classe TForm1? Magari nel costruttore, per restituire un riferimento
all'istanza?
Però comunque è necessario dichiarare da qualche parte (e poi gestire)
un puntatore a TForm1 che sia di riferimento per chi deve avere a che
fare con l'istanza, no? Una volta creata dinamicamente, ci si riferisce
ad essa sempre con un puntatore. E chi/come lo gestisce? E chi deve
conoscerlo per usare l'istanza di TForm1, dove lo va a cercare?
Inoltre... volendo gestire dinamicamente più form che devono interagire
fra loro, è necessario creare una classe "registrar" che tiene traccia
di chi c'è e chi non c'è più e passa dati e comandi fra tutte quante?
Oppure usare una classe "factory" per crearle dinamicamente e una
"commander" per farle comunicare?

 Uso C++ Builder 3
Probabilmente arrivo buon ultimo, lo riporto a futura memoria per chi,
disperato, un giorno leggerà questo thread come estrema risorsa...
C++Builder crea tutti i form all'inizio nella WinMain:
//---------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    try
    {
         Application->Initialize();
         Application->Title = "MiaApplicazione";
         Application->CreateForm(__classid(TForm1), &Form1);
         Application->CreateForm(__classid(TForm2), &Form2);
//       ecc. ecc...
//----------------------------------------------------------------
per cui se cancelli la definizione di Form1 ti dà errore per forza :-)
...e ora mi è venuta la curiosità di andare a vedere il codice del
metodo CreateForm()... quali misteriosi e arcani maneggi farà mai??? O_O
Vado a tuffarmi nei meandri della include dir di C++Builder... se non
posto niente entro il 6 gennaio allertate la protezione civile e mandate
i soccorsi ^_^

 //----------------------------------------------------------------
In quale file si trova questo codice?
Ricordo di averlo visto ma ho visto i vari file di un nuovo progetto e
non riesco a trovarlo...
Sai se i parametri di WinMain si possono usare per conoscere il nome
dei parametri passati al programma?
Un po come char* argv[] del main del classico C++

Ho creato una array di Edit a run-time.
Adesso vorrei definire un metodo da assegnare all'evento OnClick.
Supponiamo che tale metono non faccia altro che cancellare il contenuto 
della Edit. Il problema è che nel metodo devo usare un riferimento generico 
alla Edit oppure devo passargli come parametro il nome dell'n-esima Edit. In 
pratica piuttosto che usare una sintassi tipo:
Edit1->Text = "";
Vorrei qualcosa tipo:
this->Text = ""
dove this dovrebbe puntare alla Edit che in quel momento chiama l'evento.
Come posso fare?
Grazie

insolent, by the shoulder, in an
    authoritative manner, bidding him to go out of her presence. He
    went away cowed, and they all said, as was reported to her by one
    of her attendants, 'She is not afraid'; they then became very
    superstitious at the idea of a woman taking hold of them, and
    troubled her no more.
    "The five or six Christian friends where we were staying in Canton
    all agreed that it was the most common occurrence for little girls
    to be bought and sold for immoral purposes. One of the group
    has often heard the wretched blind girls singing just under her
    window, on the river bank, and under conduct of the old
    brothel-keeper, their owner, thus attracting custom. The
    proportion of blind people in Oriental countries is much greater,
    owing to the prevalence of eye diseases and the poverty and
    ignorance of the people in coping with these, than in the West;
    and as blind girls do not bring much money when disposed of as
    wives, so they are sold in large numbers into a life of shame.
    Poor little slaves! Because they are d