Newsgroup: it.comp.lang.delphi
Titolo: oggetti e distruzione

Creo degli oggetti a runtime che come evento OnClick hanno una procedura 
  creata da me uguale per tutti gli oggetti. Il contenitore è un 
PageControl.
All'interno di questa procedura dovrei distruggere tutti gli oggetti che 
ho precedentemente creato chiamando PageControl.free ma mi si verifica 
un eccezzione.
Se distruggo gli oggetti in un'altra chiamata funziona tutto.
In pratica ho un oggetto creato a Runtime  piu oggetti chiamati Panel1 
.2.3.4 etc
all'evento OnClick è associata la procedura Edit
nella edit ho scritto:
if (Sender as Tpanel) then PageControl.free;
e qui si verifica l'errore.
Come posso evitare l'errore mantenendo al funzionalità ?
Daniele

 Come posso evitare l'errore mantenendo al funzionalità ?
Credo che il tuo problema derivi essenzialmente dal fatto che distruggi 
i componenti da un metodo che viene richiamato da loro stessi.
Potresti introdurre un metodo nel Form che esegua tale distruzione; 
invece di richiamare il metodo direttamente, invia un messaggio 
specializzato all'applicazione che venga intercettato dal Form e che 
provochi l'esecuzione del suddetto metodo; nella dichiarazione del 
metodo, utilizza la direttiva *message* per indicare che esso verrà 
richiamato solamente alla ricezione di un determinato messaggio 
(consulta la Guida in linea per maggiori informazioni).
Quando è necessario distruggere i componenti interessati, invia tale 
messaggio direttamente alla coda dell'applicazione, oppure al Form, 
usando la funzione API /PostMessage/ cui passerai l'handle e la costante 
(definita da te) del messaggio.
Ciao! :-)
-- 
Marco «Alka» Breveglieri
  (marco [@] abls [.] it)
  ABLS Team S.n.c. - Software & Web
  42019 Scandiano (Reggio Emilia)
 
http://www.abls.it



Non potevi essere meno chiaro :-((
Impegnati un po' di più e raccontaci meglio la questione: perchè metti i
TPanel nel PageControl e non in una delle sue pagine (un Tabsheet)? Perchè
nel clic fai un cast di Sender a TPanel e non lo confronti con niente?
Saluti
	Marco Bortolani
	info @ 
marcobortolani.it

 
Hai azzeccato il problema ti ringrazio mi devo studiare il tuo consiglio.
Daniele

 	info @ 
marcobortolani.it
In effetti sono stato un pò avaro di dettagli ora provo a dire qualcosa 
di più senza scrivere mille righe (la sintesi non è il mio forte)
Uso il PageControl come contenitore per poter distruggere tutti gli 
oggetti che contiene in una sola istruzione (Free).
Uso il TPanel come contenitore di TLabel e TJPEGImage
a runtime creo n Panel (con una funzione che mi restituisce il Panel 
appena creato)  con i relativi oggetti figli (Label e JPeg) associati 
tramite la proprietà parent al panel.
La funzione edit è associata all'evento OnClick di ogni oggetto creato 
in precedenza
il prototipo di edit:
procedure TForm1.Edit(Sender: TObject);
il corpo di edit:
if (Sender as TLabel) then begin
	PageControl.Free;
e qui vien fuori l'errore.
Spero di essere stato esauriente
Daniele

 Hai azzeccato il problema ti ringrazio mi devo studiare il tuo consiglio.
Non ho aggiunto codice perchè non avevo il tempo materiale di stenderlo; 
appena mi è possibile, vedrò di postarti qualcosa.


 e qui vien fuori l'errore.
Credo che abbia ragione Marco. Se distruggi l'oggetto implicitamente (o 
esplicitamente) non c'è modo di tornare all'evento a cui l'oggetto 
puntava proprio perché l'oggetto è stato distrutto, per cui viene 
generato l'AV. Credo che il consiglio di Marco sia appropriato. Inviando 
un messaggio asincrono puoi gestire tutto direttamente dalla form senza 
costringere Delphi a tornare alla successiva istruzioni di un evento 
puntato da un oggetto che non esiste più.
guastatore

 
Saresti davvero un angelo io da parte mia stò guardando ma non sono una 
cima. Ho iniziato da poco con delphi e gli oggetti.
Daniele

 
Grazie anche a te.
Daniele

 una cima. Ho iniziato da poco con delphi e gli oggetti.
Angelo o Demone ;-)) ??
Comunque di seguito un esempio di come puoi usare il message
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  Dialogs, StdCtrls;
const
  WM_MyMessage = WM_APP + 123;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure WMMyMessage(var Msg: TMessage); message WM_MyMessage;
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.WMMyMessage(var Msg: TMessage);
begin
  PageControl.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  PostMessage(Form1.Handle, WM_MyMessage, 0, 0);
end;
ciao
guastatore

 [...]
Ottimo esempio. Avrei scritto la stessa identica cosa, ma stamattina ho 
avuto qualche problema di "connettività"... :-D
Ciao a entrambi!


 guastatore
Eccezionale era un pò in là rispetto alle mie forze attuali.
Molte grazie veramente
Daniele