Newsgroup: it.comp.lang.delphi
Titolo: Come evitare ricorsione?

Ho una procedura associata ad un evento, per semplificare le cose faccio in
modo che ne lanci un altro (click su radiobutton ---> inserimento testo in
EditBox). Dovrei fare in modo che funzioni il viceversa, evitando la
ricorsione. In C++, in casi del genere, dichiaravo una variabile statica, e
la controllavo all'ingresso e all'uscta della funzione. In Delphi non
esistono variabili statiche e non vorrei usarne una globale. Si puo' fare?


    Via De Gasperi, 14 - 42019
    Scandiano (Reggio Emilia)

 scriveva fra l'altro:

a) le variabili statiche _non esistono_ nominalmente; puoi usare senza
problemi delle costanti tipizzate sino a D5, poi diventano deprecate e,
per usarle, devi abilitarle esplicitamente con uno switch (mi pare
{$W+}, ma non sono sicuro)
b) ricorsione o reentrancy?
procedure TSomeForm.SomeProcedure(Sender: TObject);
const InSomeProcedure: boolean = False;
begin
  if InSomeProcedure then
    raise Exception.Create('Cattivello');
  InSomeProcedure := True;
  try
    ...
  finally
    InSomeProcedure := False;
  end;
end;
Saluti
Paolo Arosio

 const InSomeProcedure: boolean = False;
So che Delphi permette di farlo, ma di solito preferisco non usare le
costanti come variabili.

 costanti come variabili.
Un oggetto singleton che controlli negli eventi?
Andrea

 costanti come variabili.
Ulteriori alternative (oltre al campo o alla variabile globale):
a) disabiliti il controllo che scatena l'evento
b) distacchi l'handler all'ingresso nella procedura e lo riattacchi alla
fine
c) crei una classe che ti consenta di fare cio' che desideri
d) metti un acquire criticalsection o qualcosa di simile all'inizio
della procedura
e) ...
Saluti
Paolo Arosio

e non vorrei usarne una globale. Si puo' fare?
// C++
int myfunc()
{
    static int pippo;
    ++pippo;
}
// Delphi
function MyFunc: Integer;
const
  Pippo: Integer = 0;
begin
  Inc(Pippo);  
end;
-- 
Andrea Laforgia
www.geocities.com/andrealaforgia
"640kb of memory should be enough for anyone." -- Bill Gates.

Evento A -> procedure A -> uscita immediata.
Dio mio, ma a che ti serve tutto questo ??


 Dio mio, ma a che ti serve tutto questo ??
A rendere il programma piu' divertente... :-) :-) Vuoi mettere che pizza,
altrimenti, a forza di Caption, Dataset, TblUtenteCodiceFiscale.Value....
Ci sono 2 radiobutton, e 1 campo di testo: se seleziono uno dei 2
radiobutton, devo scrivere un numero nel campo di testo. Se scrivo un numero
direttamente, devo aggiornare lo stato dei radiobutton (a seconda che il
numero sia zero oppure no). In entrambi i casi devo fare un calcolo, e l'ho
messo nell'handler del campo di testo.
Era una cosa che facevo anche in C++, ma bastava una variabile statica e si
risolveva tutto...

messo nell'handler del campo di testo.
Scusa, ma le variabili statiche non mi sembra c'entrino molto.
Sull'OnChange nel campo di testo, semplicemente inserirai
l'assegnazione Checked := True del radiobutton, mentre sull'OnClick
del radiobutton ci metterai l'inserimento del valore nel campo di
testo.  Il tutto dovrà essere controllato dalla proprietà Focused, per
evitare modifiche in cascata:
procedure TForm1.Edit1Change(Sender: TObject);
begin
  if Edit1.Focused then
    RadioButton1.Checked := True;
end;
procedure TForm1.Edit2Change(Sender: TObject);
begin
  if Edit2.Focused then
    RadioButton2.Checked := True;
end;
procedure TForm1.Edit3Change(Sender: TObject);
begin
  if Edit3.Focused then
    RadioButton3.Checked := True;
end;
procedure TForm1.RadioButton1Click(Sender: TObject);
begin
  if RadioButton1.Focused then
    Edit1.Text := '1';
end;
procedure TForm1.RadioButton2Click(Sender: TObject);
begin
  if RadioButton2.Focused then
    Edit2.Text := '2';
end;
procedure TForm1.RadioButton3Click(Sender: TObject);
begin
  if RadioButton3.Focused then
    Edit3.Text := '3';
end;


 evitare modifiche in cascata:
Questo se i valori nella EditBox fossero modificabili solo tramite
inserimento diretto, oppure con il radiobutton, che non e' il mio caso. Ci
sono altri controlli che possono influire su uno o sull'altro... vorrei solo
che i 2 handler fossero richiamati entrambi, in qualunque ordine, ma non
piu' di una volta ciascuno.

inserimento diretto, oppure con il radiobutton, che non e' il mio caso.
E` una tecnica che va bene in qualunque caso.
Comunque, non hai spiegato benissimo che cosa vuoi fare.


 Comunque, non hai spiegato benissimo che cosa vuoi fare.
Hai ragione, pensavo che ci fosse una risposta sempilce alla domanda
iniziale (esiste qualcosa di equivalente alle variabili statiche?), e non ho
dato molti dettagli.
Uno dei 2 radiobutton imposta il valore a zero, l'altro esegue un calcolo e
scrive il risultato nella editbox.
La stessa editbox e' in realta' una TDBEdit, quindi collegata a un campo di
una tabella, e quando il contenuto e' zero, passando da AfterScroll devo
accendere il primo radiobutton, altrimenti devo accendere il secondo.
Con la tua soluzione, se il valore della EditBox viene cambiato dal DB (e
quindi la casella di testo non ha il fuoco) non si accende il radiobutton
giusto, e' una delle soluzioni che avevo gia' provato...