Newsgroup: it.comp.lang.delphi
Titolo: Serie di form non modali - Parte II -

Ciao a tutti,
     come anticipato .... mi sono documentato, ho testato e riporto le 
conclusioni (di certo migliorabili).
Un rispolvero al problema, in una form (non la principale) viene 
visualizzata una lista di ordinativi gia' eseguiti (se ci sono) ad un certo 
fornitore.
Cliccando sulla lista si apre una form non modale che visualizza l'ordine 
precedentemente salvato in formato pdf.
Ma se al fornitore sono stati fatti, in passato, diversi ordini e' possibile 
che per vedere la storia degli ordini si possano aprire n form visualizanti 
n ordini.
Il mio problema era come gestire queste form.
Ecco come ho risolto !!!
[ Prima un po di boring ....]
Mi sono inventato un nome da attribuire alla form pe esempio FrmDnl seguito 
da un numero che recupero dall'itemindex della lista, in questo modo non 
c'e' possibilta' di avere (anche per caso) una form doppia.
Prima di aprire la finestra, controllo se esiste gia' ..... se c'e' non la 
creo.
Infine la finestra si puo' chiudere in modo singolo oppure, quando si chiude 
la form della lista, si deve chiudere in automatico alla chiusura della 
principale (principale di questa parte del progetto).
[ Fine boring ....]
Apertura della form ..
procedure TFGO.BT2Click(Sender: TObject);
Var FRM : TFMF; // e' la mia form
begin
   if LV1.ItemIndex=-1 then Exit;
   // Controllo se la form esiste gia' -----
   if Not IsFormOpen('Form_Dnl'+IntToStr(LV1.ItemIndex)) t hen
   Begin
        FRM:=TFMF.CreateNew(Nil,NomeFile,False);
        FRM.Name:='Form_Dnl'+IntToStr(LV1.ItemIndex);
       FRM.Show;
    End;
end;
Dove LV1 e' la lista, il createnew e' un create personalizzato.
La chiusura della form se e' fatta dal suo bottone ok altrimenti si deve 
trovare il modo di chiuderla ...
Ecco come ho fatto
procedure TFGO.FormClose(Sender: TObject; var Action: TCloseAction);
Var A : Byte;
    F : TForm;
begin
  // Prima di chiudere controllo se ci sono delle form di visualizzazione 
ordine attive, se si le devo chiudere
  for A:=0 to LV1.Items.Count-1 do
  Begin
    if IsFormOpen('Form_Dnl'+IntToStr(A+1)) then
    Begin
      F:=GetOpenForm('Form_Dnl'+IntToStr(A+1));
      if F<>Nil then
      Begin
        F.Release;
        F:=Nil;
      End;
    End;
  End;
end;
Ed ecco infine il codice delle due funzioni utilizzate sopra
http://www.swissdelphicenter.ch/torry/showcode.php?id=1693
function IsFormOpen(const FormName : string): Boolean;
var
  i: Integer;
begin
  Result := False;
  for i := Screen.FormCount - 1 DownTo 0 do
    if (Screen.Forms[i].Name = FormName) then
    begin
      Result := True;
      Break;
    end;
end;
function GetOpenForm(const FormName : string): TForm;
var
  i: Integer;
begin
  Result := Nil;
  for i := Screen.FormCount - 1 DownTo 0 do
    if (Screen.Forms[i].Name = FormName) then
    begin
      Result := Screen.Forms[i];
      Break;
    end;
end;
In effetti ..... non era poi cosi' insuperabile come problema .... ma alla 
fine quello che conta e' la soluzione !!!
Spero sia utile a qualcuno !!
Alla prossima,
Ciao
Daniele 
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4951 (20100317) __________
The message was checked by ESET NOD32 Antivirus.
http://www.eset.com


Invece delle 2 funzioni "IsFormOpen" e "GetOpenForm" si potrebbe usare 
una lista, per comodità una TStringList, dove mettere la lista delle 
form che creo e con i metodi forniti dalla mia lista cerco se una form è 
già creata (.Find), nel caso aggiungo (.AddObject), oppure cancello 
(.Delete), ma credo che il succo non cambia :)
Demo sulla falsa riga del tuo codice:
oListaForm: TStringList;
TMyForm classe derivata da una TForm
Per togliere il riferimento alla lista devo far in modo che il close di 
una TMyForm richiami un mio customclose, dunque nella classe TMyForm 
avro' una property OnCustomClose: TCloseEvent;
procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   if Assigned(OnCustomClose) then
     OnCustomClose(Sender, Action);
end;
procedure TForm.ApriClick(Sender: TObject);
Var FRM : TMyForm; // e' la mia form
     nIdx: Integer;
     sNome: String; // comodo x debug
begin
   if LV1.ItemIndex=-1 then Exit;
   sNome := 'Form_Dnl'+IntToStr(LV1.ItemIndex);
   if not oListaForm.Find(sNome, nIdx) then  // se la form non è trovata
   begin
      FRM:=TMyForm.Create(Self);
      FRM.Name:='Form_Dnl'+IntToStr(LV1.ItemIndex);
      FRM.OnCustomClose := FormCustomClose;  // per toglierla dalla lista
      oListaForm.AddObject(sNome, FRM);
      FRM.Show;
   End
   else  // se la trovo la riporto in show
     (oListaForm.Objects[nIdx] as TMyForm).Show;
end;
Dunque tolgo il riferimento alla lista
procedure TForm.FormCustomClose(Sender: TObject; var Action: TCloseAction);
Var nIdx: Integer;
begin
   oListaForm.Find((Sender As TMyForm).name, nIdx);
   oListaForm.Delete(nIdx);
   Action := caFree;
end;
Alla chiusura scateno i vari close nel caso ci fosse qualche cosa di 
interessante
procedure TForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   while Not(oListaForm.Count = 0) do
     (oListaForm.Objects[0] as TMyForm).Close;
   oListaForm.Free;
end;
Potrebbe essere una variante interessante :)
^_Goblin_^
-- 
Ibis et redibis non morieris in bello
http://goblinland.myminicity.com/

 Potrebbe essere una variante interessante :)
Direi eccezionale ......
Grazie ancora
Ciao
Daniele 
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4952 (20100317) __________
