Newsgroup: it.comp.lang.delphi
Titolo: Problema sui puntatori a TPpanel

Per motivi di disegno interfaccia, a runtime alloco divesi panel (pnl_main),
ognuno di quali contiene un panel (pnl_img), e ognuno di questi contiene a sua
volta un TImage.
Im mio problema e' che devo modificare questa TImage, ma non riesco a fare il
"downcast", partendo dal puntatore del panel contenitore.
Mi lancia un classico EAccesViolation che mi fa diventare matto.
mi spiego:
type 
   pPanel = ^TPanel;
var 
   pnl_main,pnl_Img : pPanel;
   cmp,cmp1 : TComponent;
   pnl : TPanel;
begin
   pnl_main := TMiaClasse.GetPanelDisegno; // ritorna l'indirizzo del panel
   cmp := (pnl_main as TPanel).FindComponent('pnl_Img1');
   ^^^^^^^^^ QUI SCOPPIA ^^^^^^^^^
 
   if Assigned(cmp) then begin      
      cmp1 := cmp.FindComponent('img1');
      if Assigned(cmp1) then begin 
         (cmp1 as TImage).Picture.LoadFromFile('pippo.jpg');
      end
   end;
 
end;
Dov'e' lo sbaglio ??
-- 
Morde. 
(morde at programmer dot net)

    pPanel = ^TPanel;
TPanel è già un *puntatore*....
Acqua
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

    pnl_main := TMiaClasse.GetPanelDisegno; // ritorna l'indirizzo del
panel
TMiaClasse č una classe o un'istanza di una classe?
GetPanelDisegno č una Class Function?
Prova a verificare se pnl_main č <> nil.
---
Ciao
Ruggero

TPanel è già un *puntatore*....
Giusto!
La mia scarsa conoscenza della vcl mi ha portato a questo errore di
progettazione. 
Grazie per l'aiuto!


Prova a verificare se pnl_main è <> nil.
Grazie per l'interessamento, ho progettato male la classe, vedi mia risposta
ad Acqua.
Ciao!



Open Delphi Manual (
http://groups.yahoo.com/group/delphi_open_manual/
)

"brainstorming" che potrebbero sorgere. ;-)
Grazie Marco, non so se definire il tuo stile "gentilezza delicata" o
"delicatezza gentile", cmq sia tu sei nato per scrivere! Non hai mai pensato a
scrivere qualche racconto, romanzo, saggio ? Hai la stoffa, credimi, su queste
cose ho fiuto!:-)
Dunque, tornando in topic: sto realizzando un software per un centro estetico.
L'intefaccia deve poter gestire n macchine abbronzanti, mostrandone lo stato e
registrando l'attivita' sul db.
Quello a cui si riferiscono i miei post e' l'interfaccia che, in base al
numero di macchine presenti, deve essere in grado di ridisegnarsi.
L'interfaccia si collega ad una classe che rappresenta la macchina stessa,
alla quale per comodita' di ridisegno ho aggiunto dei metodi che permettono di
memorizzare il TPanel che contiene la rappresentazione grafica della macchina.
Per posizionare correttamente la bitmap che rappresenta lo stato della
macchina, oltre alle altre informazioni riguardanti il tempo di utilizzo, ecc,
faccio uso dei TPanel. Come per le matrioske, aggiungo panels dentro panels,e
dentro ai vari panel ci metto il componente che devo visualizzare: giocando
sugli alignment e sulle constraint riesco ad ottenere un posizionamento
adatto.
Il problema che avevo evidenziato e' quello per l'appunto di risalire alla
bitmap che mostrava lo stato della macchina (accesa, riscaldamento,
raffreddamento, spenta, indeterminata): il primo errore era dovuto alla mia
scarsa conoscenza della vcl (^Panel), e il buon Alex mi ha dato la dritta
giusta per risolverlo. Poi, dopo, mi sono imbattuto invece in quello che
dicevi tu ;) ossia quando ripescavo la bitmap da panel contenitore,
findcomponent ritornava nil! 
Era dovuto proprio al parent bagliato!
Il codice giusto, semplificato, lo riporto qui:
pnl_main := TMacchina.GetPanelDisegno;
pnl_Img := (pnl_main.FindComponent('pnl_img1') as TPAnel);
if Assigned(pnl_Img) then begin   
   Img := (pnl_Img.FindComponent('img1') as TImage);
   if Assigned(Img) then begin
      img.Picture := nil;
      img.Picture.LoadFromFile(nomefile);
   end;
end;
Il problema evidenziato da te era riferito alla fase di creazione e
incapsulamento dei vari panels, dove sbagliavo ad assegnargli i parent!
Ora e' tutto a posto!
Mi rendo conto di essere stato prolisso fin troppo, ma oggi va cosi'...
perdonatemi ng!


 cosi'... perdonatemi ng!
No problem. :-)


runtime; 
Questo e' interessante, ma come fai a renderli dinamici? Cioe', io l'elenco
delle macchine del centro in questione lo leggo dal db ogni volta. Questo per
permettere un domani l'utilizzo del programma in qualsiasi centro con
qualsiasi numero di macchine.
Se mi spieghi come si fa a dinamicizzare i frame in questo modo, proverei a
passare a questa tecnica.
Il discorso owner <> parent lo conoscevo dai tempi del c++, purtroppo ogni
tanto inciampo ancora in questo paradigma! Ah ah ah... mi ricordo ancora la
frase a martello del mio "tutor" di programmazione: "il parent e l'owner non
sono la stessa cosa.... il parent e l'owner non sono la stessa cosa... ecc.."
^___^


 proverei a passare a questa tecnica.
Diciamo che ogni macchina, avente caratteristiche proprie, viene
rappresentata da un frame dotato di un'interfaccia visuale adatta a
visualizzarne le proprietą; in poche parole, crei una classe frame che
ti permetta di configurare una macchina o visualizzarne lo stato (non so
bene cosa devi fare, ma il discorso non cambia).
Successivamente, puoi dotare questo frame di metodi e proprietą che
permettano di caricare al suo interno i dati della macchina: imposti il
valore di una proprietą. Per fare un esempio, potresti inserire una
CheckBox che mostri se una macchina č attiva o no, definire una
proprietą Active che faccia da "wrapper" e modifichi l'interfaccia
(aggiunga o tolga la spunta dalla CheckBox) in base al valore che viene
impostato su di essa. Un approccio simile puoi usarlo anche per tutte le
altre caratteristiche della macchina.
Quando carichi i dati delle macchine dal database, per ogni macchina
individuata crei un'istanza di questo frame, quindi crei un'interfaccia
che č in grado di visualizzare le caratteristiche della macchina in
esame; poi, imposti le proprietą del frame appena creato usando i dati
provenienti dal DB, ad esempio ponendo la proprietą Active del frame
uguale al campo ACTIVE della tabella dati.
Se ti serve mantenere un elenco dei frame per comoditą, per eventuali
scansioni, puoi creare nel form ospite un'istanza di TList e memorizzare
al suo interno tutti i frame creati a seguito del caricamento dei dati
dal DB. Ad ogni record/macchina, corrisponde un frame da creare e da
mettere in lista nel quale vengono copiate le proprietą della macchina
affinchč esso sia in grado di visualizzarle correttamente attraverso il
codice definito nella classe del frame, che viene scritto una volta sola
e utilizzato da tutte le istanze.
Spero di aver spiegato bene, almeno concettualmente, quello che intendo.


Spero di aver spiegato bene, almeno concettualmente, quello che intendo.
Si, l'ho letta e risulta linearissima.
quello che cambia e' che tu hai utilizzato un frame per disegnare
l'interfaccia mentre io, proprio a causa della scarsa conoscenza della vcl :(,
ho usato il metodo capuozzo, ossia ridisegno l'interfaccia tutte le volte
scansionando una tobjectlist che memorizza i riferimenti delle mie macchine.
Concettualmente, il mio ^TPanel puntatore che ha dato origine a questo thread
e' il tuo tframe.
Ci provo e ti faccio sapere. 
Grazie :)
