Newsgroup: it.comp.lang.delphi
Titolo: Proprietà di un frame

Ho una Form chiamata "A" in cui c'è un menu.
Dal menu seleziono una voce che deve:
richiamare il form "B" in modo modale, sul pannello del form "B" ci deve 
"appiccicare" l'oggetto Frame "C" (se non esiste lo deve creare)
Io ho fatto questo codice sul menu del form "A":
TC = classe frame
C  = nome oggetto frame
B = nome del Form B
if (B.FindComponent("C") = nil) then TC.Create(self);
   with (TC(FindComponent("C")) do
       begin
         Parent:=B.Pannello;
         Align:=alclient;
         Visible:=true;
       end;
FormB.ShowModal;
....ovviamente il codice sopra non funge. Ho capito che l'errore 
principale stà nel with.
Ho anche provato a scrivere: with (B.FindComponent("C") do.... ma niente.
Ciao e grazie
Gianni

 Ho anche provato a scrivere: with (B.FindComponent("C") do.... ma niente.
Credo che ci siano alcuni errori sia dal punto di vista della 
progettazione, sia dal punto di vista del codice a livello funzionale.
Secondo me, il codice che hai scritto dovrebbe essere inserito nella 
classe che implementa il form "B", poichè ritengo maggiormente 
appropriato che sia il form stesso ad occuparsi della creazione del 
Frame che deve essere visualizzato all'interno del proprio pannello.
Nel codice che hai postato, inoltre, viene passato /Self/ come "owner" 
del Frame creato; suppongo che /Self/ identifichi l'istanza del form 
chiamante su cui è presente la voce di menu, quindi il Frame verrà 
distrutto solo quando il form chiamante verrà distrutto, e non quando è 
il form modale secondario ad esserlo.
L'uso di /FindComponent/, poi, utilizza un nome per riferirsi al Frame e 
tale nome non viene impostato quando il Frame viene creato (se non 
esiste), impedendo quindi di trovarlo e di eseguire le dovute 
impostazioni del Parent e altre proprietà.
Non sono al corrente dei compiti dell'applicazione, quindi non posso 
dire con certezza se la soluzione adottata sia o no una complicazione, 
tuttavia io inserirei semplicemente il Frame (attraverso la Palette dei 
Componenti) direttamente nel form secondario in fase di progettazione 
(designtime); il form è quindi in grado di creare e distruggere tale 
frame, come tutti gli altri componenti, poichè essa stessa è l'owner.
Il form dovrebbe essere inoltre creato sfruttando un costrutto 
*try...finally* per gestirne la distruzione quando il form modale viene 
chiuso. Il Frame viene creato assieme al form.
Come dicevo prima, non sono al corrente dell'esistenza di forzature che 
ti hanno portato a scegliere la soluzione presentata, ad ogni modo io 
(riassumendo) procederei così:
1)
selezionando "Frames" dalla Palette dei Componenti, metterei il Frame 
interessato all'interno del form modale secondario;
2)
nella voce di menu che richiama il form modale, farei una semplice 
creazione del form e una distruzione usando il costrutto *try...finally*;
   procedure TMainForm.MenuClick(Sender: TObject);
   var
     MyModalForm: TMyModalForm;
   begin
     MyModalForm := TMyModalForm.Create(nil);
     try
       MyModalForm.ShowModal;
     finally
       MyModalForm.Free;
     end;
   end;
3)
il form modale secondario crea automaticamente qualsiasi componente e 
controllo che si trova al suo interno, incluso il Frame in esame; se 
ritieni necessario eseguire inizializzazioni riguardo il Frame, puoi 
inserire il codice necessario nell'evento /OnCreate/ della classe del 
form secondario.
   procedure TMyModalForm.FormCreate(Sender: TObject);
   begin
     // esempio indicativo
     MyFrame.Align := alClient;
   end;
Ciao! :-)
-- 
Marco «Alka» Breveglieri
(marco [@] abls [.] it )
  ABLS Team S.n.c. - Software & Web
  42019 Scandiano (Reggio Emilia)
 
http://www.abls.it

 dire con certezza se la soluzione adottata sia o no una complicazione,
Ho un applicazione con una Finestra principale in cui ho un menu ed un 
bel pannellone in cui inserisco di volta in volta il frame desiderato. 
Se ad esempio premo sul menu "Soggetti", l'applicazione crea l'oggetto 
"Soggetti" (dal frame Soggetti) e lo piazza nel pannello. Se preme su 
"Articoli" crea l'oggetto "Articoli" (dal frame Articoli) e lo piazza 
sul pannello e cosě via. Ogni frame ha lo stesso nome del menu, quindi 
quando premo sul menu non faccio altro che eseguire questa funzione e 
passare il nome fisico del menu (parametro stringa NomeFrame):
procedure 
TFormPrincipale.RichiamaFrameSoggetto(Pannello:TcxGroupBox;NomeFrame:string);
begin
// ***********************************************
// ******** Visualizza il frame Soggetto *********
if (NomeFrame='Soggetti') then
   begin
   if (FormPrincipale.FindComponent(NomeFrame) = nil) then 
TSoggetti.Create(self);
     with (Tsoggetti(FindComponent(NomeFrame))) do
       begin
         Parent:= Pannello;
         Align:=alclient;
         Visible:=true;
       end;
   end;
// **********************************************
ecc... ecc....
Fin quě tutto bene, funziona alla perfezione (ovviamente ho anche una 
funzione che nasconde o elimina gli oggetti frame inutilizzati).
Ora mi sono chiesto:
tutto questo va bene per gestire i frame clienti, fornitori, articoli, 
documenti ecc... ma per tutte quelle piccole tabelle tipo: iva, 
pagamenti, banche ecc... vorrei visualizzarli in un pannello di una 
finestra modale. A questo punto  ho pensato di modificare la funzione 
sopra ed aggiungerci la gestione di questa finestra (unica) in cui creo 
di volta in volta il frame che mi serve e la visualizzo.
E quě, gira che ti rigira, ho incontrato molti problemi e stranezze 
dovute probabilmente al fatto (come tu mi spiegavi)del "self".
Vedrň di creare una funzione simile a quella sopra direttamente sulla 
finestra modale (preferivo avere tutta questa gestione sul form 
principale, ma non voglio certo ammattire :-)
Grazie dell'aiuto
Gianni

 sul pannello e cosě via. 
Intanto la procedura sopra l'ho riscritta in questo modo (devo 
migliorarla - La procedura l'ho presa da un libro di marco Cantů):
type
  TFrameClass = class of TFrame;
{$R *.dfm}
procedure TFormPrincipale.RichiamaFrame(NomeFrame:string);
var
   Frame: TFrame;
   FrameClass: TFrameClass;
begin
Frame := FindComponent (NomeFrame) as TFrame;
if not Assigned(Frame) then
   begin
     FrameClass  := TFrameClass (FindClass('T' + NomeFrame));
     Frame := FrameClass.Create (self);
     Frame.Parent:= FormPrincipale.cxGroupBox;
     Frame.Align:=alclient;
     Frame.Visible:=true;
     Frame.Name:=NomeFrame;
   end;
Frame.BringToFront;
end;
// Registrazione delle Classi
initialization
    RegisterClass(TSoggetti)
In questo modo premendo su un menů mi carico il frame che preferisco 
passando unicamente il nome del frame (ovviamente le classi da caricare 
devono essere elencate nella sezione initialization posta prima del end 
finale. Devo un attimo adattarla meglio al mio caso, ma ci siamo. Per 
quanto riguarda il caso del form modale, l'ho risolto scrivendo un 
apposita procedura posta sul modale stesso
Ciao e grazie
Gianni