Newsgroup: it.comp.lang.delphi
Titolo: Cambiare proprietà a runtime

[Delphi 3]
Kupo... è parecchio tempo che non posto qua, ma vorrei comunque salutare chi
mi riconosce :)
Veniamo al dunque: io vorrei poter settare le proprietà dei componenti a
runtime mediante il loro nome.
In pratica, se io voglio cambiare la caption ad una label, è logico che
basterebbe fare
(FindComponent(sNomeLabel) as TLabel).Caption := 'ciao mamma';
Il fatto è che nel mio caso non saprei a priori il tipo di componente, che
quindi potrebbe essere TLabel come TPanel.
Siccome non posso certo fare
(FindComponent(sNome) as sTipo).Caption   (magari ^_______^),
il problema nasce dal fatto che la proprietà Caption, come molte altre, al
livello comune TControl (o anche TWinControl) non è né public né published,
e quindi il compilatore dà ovviamente errore.
A complicare ancora di più la situazione aggiungeteci che dovrei poter
cambiare anche le proprietà per nome (non tutte, diciamo solo quelle che so
essere di tipo String, e almeno qua si semplifica, altrimenti era un macello
:)), quindi avere alla fin fine una procedura di questo genere
procedure SetPropByName(sComponentName, sProperty, sValue: String);
o eventualmente
procedure SetPropByName(sComponentName, sType, sProperty, sValue: String);
Una stupidata, insomma ^___^;;
Beh, ho esposto... qualche suggerimento???
Grazie e a risentirci, kupo!
Jax

 (FindComponent(sNomeLabel) as TLabel).Caption := 'ciao mamma';
Delphi permette di fare una cosa del genere con le RTTI
(run-time-type-information).
Puoi enumerare le proprieta' e i metodi (ovviamente solo public e published)
e usarli comodamente.
Naturalmente e' molto piu' lento che usarli direttamente...
Purtroppo adesso non posso fornirti un esempio, cmq dovresti trovarne su
DSP.
Per imparare ad usarli puoi comprare Delphi Developer Handbook.
Ciao Uberto

 Beh, ho esposto... qualche suggerimento???
Penso che Uberto ti abbia dato la risposta migliore e sicuramente efficiente
(direi anche che è particolarmente impegnativa)...
Mi è solo balenato per la testa che forse potresti usare una libreria che si
chiama R&A Library che dovrebbe permetterti di eseguire degli "script"
Delphi...
Spero di non averti detto una vaccata, ma almeno posso coglere l'occasione
per salutarti !
Ciao :-)
--
(¯`·.¸¸.·´¯`·.¸¸.-> Andrea <-.¸¸.·´¯`·.¸¸.·´¯)
AntiSpam: rimuovere il trattino basso dall'indirizzo per rispondere
AntiSpam: remove the underscore from the e-mail address to reply

 Per imparare ad usarli puoi comprare Delphi Developer Handbook.
A trovarlo quel libro...
Kupo e grazie :)
Jax

 per salutarti !
Grazie!
Ma tutti gli altri (Nando, Umibozu, Mr. Coke...) dove sono finiti?
Kupo
Jax

 Ma tutti gli altri (Nando, Umibozu, Mr. Coke...) dove sono finiti?
Nando, LazyBoy e Mr.Coke li trovi sui newsgroups di Marco Cantu ( cfr
www.marcocantu.it
 per info + dettagliate su come accedervi), Umi mi pare che
ogni tanto lurki ancora questo ng (mi pare fosse intervenuto qualche mese
fa)...
Zortek (alias Sandro) è un po' che non lo si sente, idem per Claudio
Driussi... [troppo lavoro? :-) ]
Beh, spero di rileggerti presto, non volatilizzarti di nuovo ! ;-))


 A trovarlo quel libro...
Perche' ? non si trova ?
Marco stava pensando di farne una versione aggiornata solo su CD. Prova a
domandarglielo nei suoi ng.
Ciao Uberto

 domandarglielo nei suoi ng.
Alla fine l'arte di arrangiarsi la vincerà :))
Ciao e grazie ancora ^___^
Jax

 Beh, spero di rileggerti presto, non volatilizzarti di nuovo ! ;-))
Vedremo, se mi daranno un bell'accesso internet sul lavoro...
Grazie 1000 intanto
Jax

 Perche' ? non si trova ?
Neanch'io sono ancora riuscito a recuperarlo (Bergamo)... :-(
Ciao,grazie :-)


 bocca con tutta la lingua e pure un pezzo di fegato :))
Devo procurarmi una cintura di castità ?? :-)
Mi dici in che sezione l'hai trovata... (ironia della sorte io non riesco +
a trovarla)...
Cmq con le RTTI (ora che Uberto ci ha illuminato) sembrerebbe semplice [così
evito anche il baciozzo!!! ;-)]...
Ciao :-)


 un'occhiata.
Gli ho dato un'occhiata e in effetti è ottima la cosa, e soprattutto
funziona (mediante SetStrProp), solo che ho due grossi problemi (ok ok sono
incontentabile ^___^)
Primo: non so come si potrebbe fare a cambiare le proprietà indicizzate
(tipo Listbox1.Items[0])
Secondo: non riesco a far cambiare proprietà non dirette, cioè vediamo se mi
spiego, riesco a cambiare Label1.Caption ma non Label1.Font.Name... ho
provato a fare una procedura semiricorsiva che prenda man mano come Owner i
componenti stessi (prima Form1, poi Label1, poi Font e da lì la sua
proprietà Name) ma cazzarola, TFont (è l'unico esempio che sono riuscito a
vedere) non ha un owner, quindi facendo Label1.FindComponent('Font') ottengo
nil.
O almeno credo che sia quello il motivo, può anche darsi che Font non sia un
TComponent e per questo non lo trovi, non so. Sono un po' stanchino forse
^__^;
Uberto, sei la mia unica speranza, come sempre :)
Jax

 TComponent.Name e assegnare di conseguenza...
Come non detto, ho scritto una boiata...


 nil.
Questo non puoi farlo perche' TFont non deriva da TComponent e quindi non ha
un owner
 Ciao Uberto

Neanch'io sono ancora riuscito a recuperarlo (Bergamo)... :-(
Qualsiasi libreria universitaria dovrebbe riuscire ad ordinarlo.
Altrimenti Amazon o Milano. 
Ciao Uberto


Come promesso ecco il codice per leggere una "sotto-proprietà" in pratica
una volta capito come leggere una proprietà di tipo classe il resto e'
banale. Lo stesso sistema lo puoi usare per le proprietà indicizzate
(tipo gli Items di una Listbox) perché nel caso siano published non sono
altro che la proprietà di default di una classe. Non mi pare sia
possibile leggere proprietà o metodi public... 
  var
    obj: TObject;
    pp, pp2: PPropInfo;
    pt: integer;
  begin
  obj := findComponent( edit1.text ); // o quello che vuoi
  pp := GetPropInfo( obj.classinfo, 'items' ); // <---- Nome proprietà
  if not assigned ( pp ) then
    raise Exception.Create( 'La proprietà non esiste !' );
  if pp.PropType^.Kind = tkClass then
    begin 
    pt := GetOrdProp( obj, pp ); // <---- Qui ho l'oggetto. Il resto
    sarebbe inutile basterebbe un typecast a TFont pp2 := GetPropInfo(
    TObject( pt ).ClassInfo, 'strings' ); // <----- Nome sotto proprietà 
    if assigned( pp2 ) then
      showmessage( GetStrProp( TObject( pt ), pp2 ) );
    end;
  end;
Ciao Uberto