mecoman:
Ciao a tutti. Come avete letto nell'oggetto del topic devo fare una cosa un pò "strana".
Sto scrivendo un'applicazione composta da 2 form. Nel secondo form ho inserito un button che deve eseguire, dopo alcune istruzioni, una intera procedure presente nel form1. Come faccio a richiamare dal form2 una procedure presente nel form1?
Tengo a precisare che non posso semplicemente ricopiare la procedure del form1 nel form2...
Grazie a chiunque possa aiutarmi.
nomorelogic:
In TForm2 dovresti dichiarare una proprietà che punta ad una istanza di TForm1 tipo:
TForm2 = class... private FAltraForm: TForm1; // <- questa riga non la scrivere perchè ti compare dopo aver schiacciato la combinazione di tasti sotto public property AltraForm: TForm1 read FAltraForm write FAltraForm; // quà schiaccia Ctrl + shift + C end;
a questo punto: Form2.AltraForm.LanciaProcedura(...); // a patto che LanciaProcedura sia public in TForm1
Narciso:
MHA...
Io dichiarerei un uses nomeform1...
e poi richiamerei col button...
formnomeform.nomeprocedura;
Stilgar:
Allora mecoman. In informatica ci sono almeno 10 strade per ottenere lo stesso risultato. Facciamo un attimino di "base comune". 1) Hai 2 Form. 2) Form2 Richiama Form1. 3) Per far scattare il metodo della form1 (procedura mi fa presupporre che non sia legata all'istanza della Form1 ma dichiarata come procedura della unit1, che contiene anche la Form1).
La strada che indicava Nomore, prevede che ci sia una dipendenza diretta da Unit2 verso Unit1 (porca paletta, con l'UML ci metterei 1 secondo a rappresentarla ...) Narciso si accoda, ma non spiega bene dove vuole mettere la dipendenza. Se nella parta pubblica (come implicitamente diceva Nomore) o nella parte privata del modulo. Partiamo con gli esempi di codice:
--- Codice: --- unit unit1; //bla bla type TForm1 = class(TForm) PUBLIC <{- Altrimenti con piffero che la richiami da fuori della gerarchia delle classi !!!!} //bla bla procedure QuellaCheMiInteressaRichiamareEssendoUnRicicloneDelCodice; //bla bla End; //bla bla
--- Termina codice ---
--- Codice: --- unit unit2; Uses ..... UNIT1; <-Ipotesi di Nomorelogic type TForm2 = class(TForm) public property AltraForm: TForm1 read FAltraForm write SetAltraForm;// <- Ipotesi di Nomorelogic published // bla bla procedure OnClickButtonCheChiamaLaProcedureCheMiInteressaRichiamareEssendoUnRicicloneDelCodice(sender : TObject); // bla bla End; //bla bla implementation Uses Unit1; //<- Ipotesi di Narciso? type procedure TForm2.OnClickButtonCheChiamaLaProcedureCheMiInteressaRichiamareEssendoUnRicicloneDelCodice(sender : TObject); begin if assigned(FAltraForm) then //<- Importante questo controllo, in genere per evitare di cadere sulle dimenticate assegnazioni. FAltraForm.QuellaCheMiInteressaRichiamareEssendoUnRicicloneDelCodice; Form1.QuellaCheMiInteressaRichiamareEssendoUnRicicloneDelCodice; end; {Nell'ipotesi di nomore serve controllare il ciclo di vita degli oggetti. Devi "registrare" l'ultilizzatore come "ascoltatore". In questo modo puoi evitare di diventare matto a capire se Form1 è ancora "viva o meno" da fuoi. Questo servono RemoveFreeNotification e FreeNotification. Questi metodi sono gentilmente offerti da TComponent} procedure TForm2.SetAltraForm(const aValue : TForm1); begin if assigned(FAltraForm) then FAltraForm.removeFreeNotification(self); FAltraForm := aValue; if assigned(FAltraForm) then FAltraForm.freeNotification(self); end;
--- Termina codice --- Stilgar
Stilgar:
Per dimostrare che non esistono solo strade "semplici". Hai pensato di usare delle action? Associ il bottone ad una action. Il bottone fa scattare l'action e nell'execute dell'action associata metti la chiamata al metodo che ti interessava chiamare. Questo ha un duplice vantaggio (altrimenti non le avrebbero introdotte). 1) Centralizzi il codice, anche in un unit separata. 2) Sganci la "logica" dai componenti che la usano.