Ciao a tutti,
avendo studiato a scuola Turbo Pascal, ed avendo "imparato" ad usare fpc/Lazarus da autodidatta, ci sono alcune cose che ho imparato meccanicamente, senza ben capire i meccanismi che ci sono dietro.
Ora, sto avendo un problema, che non riesco a risolvere, a causa di una di queste cose che non capisco.
Provo a spiegare il problema ...
Ho un oggetto dichiarato così:
PopupNotifier1: TPopupNotifier;
Dovendo far eseguire delle operazioni quando un utente chiude la finestrella del popup, ho scritto questo codice:
PopupNotifier1.OnClose:=@ChiudiPopup;
La procedura "ChiudiPopup", è stata dichiarata così:
procedure TForm1.ChiudiPopup(Sender: TObject; var CloseAction: TCloseAction);
Quello che non capisco è questo: quando assegno la "OnClose", scrivo solo il nome della procedura, senza dichiarare i parametri da passargli ... da dove li ricava ?????
Provo a rifare la domanda in un'altra maniera: visto che "CloseAction" è dichiarata come "var", se in un certo punto del programma dovessi testare il valore di quella variabile, come faccio ?
Grazie, Mario
Quello che viene effettuata è una assegnazione di "puntatore", ossia assegni alla funzione OnClose (che è di fatto un puntatore e per default è nil) un nuovo puntatore a funzionne @ChiudiPopup.
In linea prettamente teorica, l'assegnazione potrebbe violare tutte le regole e il puntatore ad esempio non essere un puntatore a funzione ma ad una variabile o altro (e in questo caso a RUNTIME avresti un bel AV).
Però il compilatore PASCAL (tutti i compilatori PASCAL) DOVREBBE ESEGUIRE una verifica con la firma dei metodi, ossia con i parametri che le funziomi o le procedure dichiarano. Attenzione che non tutti i compilatori eseguono la verifica con la definizione del risultatoo (ad esempio integer o boolen) in caso di funzioni.
La definizione di OnClose la trovi nell'unità dove è definito TPopUpMenu:
TPopupMenu = class(TMenu)
private
FAlignment: TPopupAlignment;
....................
published
...............
property OnClose: TNotifyEvent read FOnClose write FOnClose;
end;
OnCLose è un TNotifyEvent, quindi la tua assegnazione è ERRATA .....
TNotifyEvent = procedure(Sender: TObject) of object;
Ha un parametro in più, CloseAction non ci stà ....
Quindi se ti viene compilato il codice, desumo che il compilatore freePascal non esegue il controllo ma fà solo l'assegnazione della procedura .....
Ciao
Provo a rifare la domanda in un'altra maniera: visto che "CloseAction" è dichiarata come "var", se in un certo punto del programma dovessi testare il valore di quella variabile, come faccio ?
Intanto qui la definizione è errata, comunque in generale quella sarebbe una variabile di tipo TCloseAction.
Quindi può assumere uno dei valori seguenti.
TCloseAction = (caNone, caHide, caFree, caMinimize);
Per default avrà un valore (presumo caNone) e la puoi testare con un IF ad esempio oppure la puoi assegnare ad uno dei valori consentiti.
Ciao
Scusami, ma credo che stiamo parlando di cose diverse: tu stai parlando di "TPopupMenu", io di "TPopupNotifier".
Probabilmente è questo il motivo per cui mi scrivi che la dichiarazione che ho fatto è errata.
Detto questo, questa è parte del codice che non mi compila:
PopupNotifier1:=TPopupNotifier.Create(nil);
try
PopupNotifier1.Icon.Assign(Form1.Icon);
PopupNotifier1.Title:=Titolo;
PopupNotifier1.Text:=MsgDaEme;
PopupNotifier1.TextFont.Color:=clBlack;
PopupNotifier1.OnClose:=@ChiudiPopup;
qui c'è un ciclo while in cui ogni secondo vorrei capire se l'utente ha chiuso o meno la finestrella di notifica, al cui interno
ho l'istruzione qui sotto:
if (CloseAction <> caFree) then begin
Il compilatore mi dice che quella variabile non esiste ...
Pardon, stamane ero di fretta e mi era sfuggito il dettaglio.
Comunque la definizione proviene parai pari da:
TCloseEvent = procedure(Sender: TObject; var CloseAction: TCloseAction) of object;
CloseAction non è una variabile appartenente alla classe, ed è usabile SOLO all'interno dell'evento ossia nella tua procedura "ChiudiPopUP".
OVVIAMENTE LA TUA PROCEDURA che hai abbinato a OnClose deve avere lo stessa definizione:
procedure TFormxxx.ChiudiPopUP(Sender: TObject; var CloseAction: TCloseAction);
begin
//qui puoi usare CloseAction
end;
CloseAction non riporta cosa l'utente ha deciso di fare, ma cosa il tuo codice vuole fare quando avviene l'evento. Sinceramente non conosco quella classe, e non riesco ad abbinare questo dato logicamente (es. caMinimize cosa fà su un popup).
Non ha quindi senso testarla con l'IF se il tuo codice non l'ha a sua volta già impostata (per default dovrebbe essere sempre caNone all'ingresso della procedura).
Ciao
Oggi era una giornata buona per rimanere a dormire.
Forse ho compreso cosa intendeva chiedere @bonmario.
La visualizzazione di un PopUP non è bloccante, ossia il codice non viene bloccato dopo la sua visualizzazione.
Quando l'utente deciderà di chiudere il PopUP, viene generato l'evento OnClose, evento che tu hai fatto puntare alla tua procedura e che quindi verrà eseguita.
Se vuoi nel tuo codice (ESTERNO ALL'EVENTO OnClose, quindi esterno alla tua procedura ChiudiPopUP) sapere quando questo è avvenuta, semplicemente usa una varibiale boolean definita globalalmente o nella tua classe Form per settarla nell'evento. Poi la puoi testare con tutta calma.
Esempio:
var PopUPChiuso: boolean;
//Da qualche parte lo inizializzi a false
// PopUPChiuso := false;
///Da qualche parte lo testi e lo rimetti a false
// If PopUPChiuso then
// begin
// ..... fai qualcosa
// PopUPChiuso := false;
// end;
procedure TForm1.ChiudiPopUP(Sender: TObject; var CloseAction: TCloseAction);
begin
PopUPChiuso := True;
end;
EDIT: Nota che il ".......fai qualcosa" lo potresti fare anche nell'evento ChiudiPopUP, compatibilmente con la tua logica e il tuo codice ....
Ciao
Grazie @DragoRosso, ho fatto come dici tu, usando "PopUPChiuso" e va bene, ma c'è una cosa che continuo a non capire ...
Se la dichiarazione è questa:
procedure TForm1.ChiudiPopUP(Sender: TObject; var CloseAction: TCloseAction);
la variabile "CloseAction", nonostante sia stata dichiarata con la clausola "var", perderà il suo valore all'uscita della procedura "ChiudiPopUP" ?
Se così fosse, che senso ha dichiararla come "var" ??
Grazie, Mario