Newsgroup: it.comp.lang.delphi
Titolo: Componenti e Form

 
        Ho un problema: ho realizzato dei componenti che aprono delle form. Il
problema č che vorrei che l'utente possa aprire piů volte la form e lavorare
contemporaneamente su di esse. Ho anche realizzato un componente che mi fa
vedere l'elenco delle form per rendere attive una di esse. Il problema sorge
nella chiusura di queste form dopo il release mi appare un EListError out of
bound che non capisco a cosa si rifirisca. Come gestire l'aperatura di piů
form utilizzando la stessa variabile?
Es:
frmProva:=TfrmProva.Create(Application);
frmProva.Show;
Se l'utente riapre questa form 3 volte accade il patatrac in chiusura, di
solito con due non succede niente.
Grazie a tutti coloro che mi vorrano aiutare.
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 solito con due non succede niente.
Credo che tu abbia autonomamente scoperto l'origine del problema: il 
fatto di utilizzare un'unica variabile per riferirti alle istanze del 
form che vengono create.
Per risolvere il problema, da un punto di vista puramente teorico, 
potresti creare un'istanza di *TList* con la quale gestire una lista dei 
riferimenti ai form che vengono creati. Se decidi di distruggere il form 
attraverso l'evento /OnClose/, preoccupati di rimuovere il riferimento 
dell'istanza stessa, identificata da /Self/, dalla lista che contiene i 
riferimenti dei form aperti.
Eventualmente, prova a fare qualche prova tecnica e a verificare sulla 
Guida in linea gli argomenti relativi alle classi che ti ho menzionato, 
poi se hai problemi o ti servono ulteriori chiarimenti, scrivi di nuovo.
Ciao! :-)
-- 
MARCO «Alka» BREVEGLIERI
   (
http://www.marco.breveglieri.name
)
Leggi le FAQ di ICLD: 
http://icld.altervista.org

 poi se hai problemi o ti servono ulteriori chiarimenti, scrivi di nuovo.
Secondo me il problema è quello che ho detto, ma non so come muovermi!
Grazie.


 Secondo me il problema è quello che ho detto, ma non so come muovermi!
Ciao,
   ho approfittato della pausa pranzo (un panino veramente orrendo oggi) 
per stenderti questo codice a puro titolo esemplificativo (del resto, ci 
ho dedicato 5 minuti). :)
Ho creato un progetto VCL Win32 e ho inserito due form, uno principale 
(TMainForm) e uno secondario (TChildForm); il primo form provvede a 
creare più copie del secondo alla pressione di un pulsante, 
memorizzandone i riferimenti in una lista; il form secondario si rimuove 
da tale lista quando esso viene chiuso (e quindi distrutto).
Ti riporto il codice della unit relativa al form principale:
========== Forms.Main.pas ==========
unit Forms.Main;
interface
uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, 
Forms,
   Dialogs, StdCtrls, ExtCtrls;
type
{ TMainForm }
   TMainForm = class(TForm)
     CreateChildButton: TButton;
     QueryChildButton: TButton;
     ChildInfoMemo: TMemo;
     CloseButton: TButton;
     LineBevel: TBevel;
     procedure QueryChildButtonClick(Sender: TObject);
     procedure CreateChildButtonClick(Sender: TObject);
   private
     { Private declarations }
     FChildList: TList;
   public
     { Public declarations }
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
     procedure AddChildForm(AForm: TCustomForm);
     procedure RemoveChildForm(AForm: TCustomForm);
   end;
var
   MainForm: TMainForm;
implementation
uses
   Forms.Child;
{$R *.dfm}
{ TMainForm }
constructor TMainForm.Create(AOwner: TComponent);
begin
   inherited Create(AOwner);
   FChildList := TList.Create;
end;
destructor TMainForm.Destroy;
begin
   if FChildList <> nil then
     FreeAndNil(FChildList);
   inherited Destroy;
end;
procedure TMainForm.AddChildForm(AForm: TCustomForm);
begin
   if FChildList <> nil then
     FChildList.Add(AForm);
end;
procedure TMainForm.RemoveChildForm(AForm: TCustomForm);
begin
   if FChildList <> nil then
     FChildList.Remove(AForm);
end;
procedure TMainForm.CreateChildButtonClick(Sender: TObject);
var
   ChildForm: TChildForm;
begin
   ChildForm := TChildForm.Create(Application);
   FChildList.Add(ChildForm);
   ChildForm.Show;
end;
procedure TMainForm.QueryChildButtonClick(Sender: TObject);
var
   ChildForm: TChildForm;
   i: Integer;
begin
   ChildInfoMemo.Lines.BeginUpdate;
   try
     ChildInfoMemo.Lines.Clear;
     for i := 0 to FChildList.Count - 1 do
     begin
       ChildForm := TChildForm(FChildList[i]);
       ChildInfoMemo.Lines.Add(Format('[%d] Left: %d - Top: %d',
        [i, ChildForm.Left, ChildForm.Top]));
     end;
   finally
     ChildInfoMemo.Lines.EndUpdate;
   end;
end;
end.
==========
Il codice del pulsante QueryChildButton ha il solo scopo di offrire un 
pretesto per scandire la lista e visualizzare informazioni sui form 
presenti a titolo di verifica del funzionamento.
Di seguito, ti riporto il codice della unit relativa al form secondario, 
molto molto semplice e scarno:
========== Forms.Child.pas ==========
unit Forms.Child;
interface
uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, 
Forms,
   Dialogs, StdCtrls;
type
{ TChildForm }
   TChildForm = class(TForm)
     CloseButton: TButton;
     procedure FormClose(Sender: TObject; var Action: TCloseAction);
   private
     { Private declarations }
   public
     { Public declarations }
   end;
implementation
uses
   Forms.Main;
{$R *.dfm}
{ TChildForm }
procedure TChildForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   Action := caFree;
   TMainForm(Application.MainForm).RemoveChildForm(Self);
end;
end.
==========
Ovviamente, è suscettibile di miglioramenti ma spero possa esserti utile 
per iniziare ad affrontare il discorso e comprendere alcuni meccanismi.
Ciao,
   Marco.
