Newsgroup: it.comp.lang.delphi
Titolo: proprietÃ  di tipo classe

Salve a tutti,
ho creato un componente con una proprietà il cui tipo è una classe.
property Border : TBorderClass Read FBorder Write FBorder;
il problema sta nel fatto che nella classe TBorderClass definisco delle 
nuove proprietà ( naturalmente nella sezione published ) per renderle 
visibili a design time, avendo una propietà:
 - Border
     Width
     Color
Il tutto viene compilato, nell'obj insp mi appare al proprietà Border col 
[+] ma non escono le sotto proprietà.
Qlc ha idea del xchè?
grazie in anticipo e buon veglione di capodanno! :)
Diego
--- posted by geoForum on 
http://www.delphiedintorni.it

 visibili a design time [...]
Innanzitutto, credo sia meglio - per convenzione - usare un altro nome 
per la tua classe che non termini per la parola "Class" che, in genere, 
si riferisce ad un tipo "class of"; ad esempio:
   TMyBorder = class
   end;
   TMyBorderClass = class of TMyBorder;
In secondo luogo, per ottenere la visualizzazione nell'Object Inspector 
e la persistenza per la tua classe, essa deve derivare almeno da 
*TPersistent*. Confermi la soddisfazione di questo requisito nel tuo 
codice? :-)
Terzo, le proprietà della classe che hai definito devono essere 
anch'esse spostate nella sezione "published" per la loro visibilità 
all'interno dell'Object Inspector. Confermi anche questo? :-)
Quarto, modifica il modo in cui esponi la proprietà nel componente che 
hai creato; invece di
   property Border: TMyBorder read FBorder write FBorder;
usa
   property Border: TMyBorder read FBorder write SetBorder;
e definisci il metodo privato SetBorder() così
   procedure TMyClass.SetBorder(Value: TBorder);
   begin
     FBorder.Assign(Value);
   end;
Dovrai poi definire nella classe del bordo il metodo Assign (con la 
direttiva "override") in modo simile a quanto segue:
   procedure TMyBorder.Assign(Source: TPersistent);
   begin
     if Source is TMyBorder then
     begin
       Self.Color := TMyBorder(Source).Color;
       Self.Width := TMyBorder(Source).Width;
       // ...altre proprietà
     end
     else
       inherited Assign(Source);
   end;
Immagino che tu ti sia ricordato inoltre di creare e distruggere 
l'instanza della classe che gestisce il bordo rispettivamente nel 
costruttore Create() e nel distruttore Destroy() della classe che 
contiene ed utilizza tale istanza...giusto? ;-)
Potrei aver dimenticato qualcosa, magari lo vediamo in caso di problemi, 
oppure posta un po' di codice significativo per chiedere eventualmente 
un chiarimento su qualche dubbio.
Ciao e buon anno!
   Marco.
-- 
MARCO BREVEGLIERI
  (
http://www.marco.breveglieri.name
)

 eventualmente un chiarimento su qualche dubbio.
Speriamo di no! mi hai fatto una pezza abbastanza!!! ^_^'
Approfitto dell'occasione per chiedere un altra cosa!
fino ad ora ho definito delle proprietà di tipo
TColor, Integer, Boolean
e ho cercato di assegnare dei valori di default da far apparire
nell obj inspector :
property Sizeable : Boolean Read FSizeable Write SetSizeable default True;
property Width : Integer Read FWidth Write SetWidth default 100;
ma non funziona, per Width mi esce il valore "0" e per Sizeable "False".
Nell'help c'è scritto che :
The default and nodefault directives are supported only for ordinal types 
and for set types
cosa ho sbagliato?


 ma non funziona, per Width mi esce il valore "0" e per Sizeable "False".
La direttiva *default* consente di informare Delphi su quali sono i 
valori predefiniti per la proprietà a cui viene applicata.
Ciò non significa che Delphi attribuisce in automatico tali valori, ma 
essi devono essere impostati all'interno del costruttore della classe a 
cui appartiene la proprietà stessa, a meno che non siano uguali a quelli 
normalmente previsti per i tipi di dati utilizzati (ad esempio, i campi 
Integer sono automaticamente inizializzati a zero).
La direttiva *default* indica a Delphi che il valore della proprietà non 
deve essere sottoposto a "streaming" (salvato nel DFM, ad esempio) 
quando equivale a quello predefinito indicato (poichè tanto è il 
costruttore ad impostare tale valore).
La direttiva *default*, come ti ha segnalato il compilatore, è 
applicabile solo ad una ristretta cerchia di tipi base; per 
problematiche più complesse, è sempre possibile utilizzare la direttiva 
*stored* (di cui trovi le istruzioni nella Guida in linea).
Ciao,


Grazie Marco per le precisazioni, sono state molto utili.
Scusa se ti faccio un altra domanda ma ho cercato on line e nei file di 
help di delphi una guida sulla creazione di componenti ma non sono 
riuscito a trovare nulla, l'unica cosa che ho sono Mastering in Delphi 
5/6 ma i capitoli sulla creazione di componenti sono molto simili e non 
riesco a trovare il caso specifico.
se hai qlc link mi farebbe comodo per studiare :)
domanda:
ho una propietà 
property Font : TFont Read FFont Write SetFont;
procedure TMiaClasse.SetFont(const Value: TFont);
begin
  FFont := Value;
end;
nel costruttore inserisco FFont := TFont.Create; 
nel distruttore inserisco FFont.Free;
quando nell'obj insp tento di cambiare font e compilo mi da un errore e 
non mi fa fare più nulla...quindi devo killare il processo delphi32.
grazie ancora.


 [...]
Questa problematica rientra nel caso che ti ho spiegato ieri: alla tua 
proprietà (cioè al campo privato che contiene l'istanza di *TFont*) stai 
assegnando il puntatore sostituendolo a quello relativo all'istanza che 
hai creato nel costruttore.
Devi usare il metodo /Assign/ della classe *TFont*:
   property Font: TFont read FFont write SetFont;
   procedure TMiaClasse.SetFont(const Value: TFont);
   begin
     FFont.Assign(Value);
   end;
In questo modo, non perdi il puntatore dell'istanza di *TFont* che crei 
all'interno del componente, ma semplicemente imposti le proprietà di 
tale oggetto affinchè abbiano gli stessi valori dell'oggetto *TFont* 
passato come parametro (Value).
