Newsgroup: it.comp.lang.delphi
Titolo: Problema gestione evento double-click

Ho creato un componente che mi mostra una form per la ricerca di un
articolo. Nel  caso l'utente faccia un doppio click su una riga del
dbgrid contenente la lista degli articoli corrispondenti ai criteri di
ricerca impostati, la fom si chiude (ModalResult=ok), e il codice
selezionato viene passato alla procedura che aveva effettuato la
chiamata al metodo del componente di ricerca.
Fin qui tutto ok: il problema che non riesco a risolvere e' questo:
quando la procedura che chiama il metodo per fare la ricerca
dell'articolo conclude la sua esecuzione, il doppio-click viene
passato anche alla form principale (ossia a quella sottostante quella
di ricerca appena chiusa), e nel caso il mouse sia posizionato sopra
una dbgrid, essa intercetta nuovamente il doppio click, scatenando
l'esecuzione della procedura associata.
Esiste la possibilità, una volta processato un evento, di inibire la
possibilità che questo venga nuovamente processato? 
Ringrazio in anticipo chiunque vorrà darmi un suggerimento.
ciao, Michele

 wrote

mi pare di aver capito il tuo problema, però non mi pare di darti una
soluzione giusta perchè vorrei vedere cosa accade esattamente e come
intervenire nella maniera migliore.
Quello che ti posso dire è che tu puoi sganciare il metodo associato ad un
evento qualsiasi.
Se tu hai un metodo del tipo:
procedure Form1.FormCreate ecc ecc....
questo sarà associato all'evento OnCreate dell'oggetto Form1.
Se tu vuoi evitare che questo metodo venga richiamato quando si scatena
l'OnCreate di Form1, tu puoi scrivere da qualche parte, questo:
Form1.OnCreate:=nil;
ed in questo modo sganci il metodo dall'evento, poi per riagganciarlo,
scrivi:
Form1.OnCreate:=FormCreate;
Tutto chiaro ?
Forse sapevi già sta cosa, comunque per ora non mi viene in mente altro
tranne giochini strani e poco belli a livello di codice.
Ciao ciao....
Antonio Tarolla

Ciao ciao....
Ok ti ringrazio per il suggerimento, ho provato a seguire la strada
che mi hai indicato e il discorso funziona: resterebbe comunque
maggiormente auspicabile, almeno a mio parere, cercare di *prevenire*
a monte il problema, inibendo la propagazione dell'evento, piuttosto
che cercare di andare a scovare e trattare in modo opportuno tutti gli
event handler che possono essere associati a quell'evento a seconda,
ad esempio, della posizione in cui si trovava il mouse al momento del
click!
Anzi mi pare che dovrebbe essere lo stesso Delphi a inibire la
propagazione di un evento gia' processato da una form che viene
chiusa, alla form sottostante ...: mi sbaglio o questo e' un bug?
ciao Michele

passato anche alla form principale
Da come hai descritto la cosa, questo meccanismo mi sembra
impossibile.  Nel senso che l'OnDblClick della DbGrid
dovrebbe scatenarsi con il doppio click sue *quella* DbGrid
ed esaurire il processamento di questo evento, senza
lasciare "residui".
Bada bene, ho scritto anch'io un programma con questa
caratteristica, ovvero un form per la ricerca di un
contratto che una volta aver riempito la sua dbgrid con i
record trovati, consentiva di aprire la maschera di
visualizzazione facendo doppio click su uno di essi.
Non ho avuto problemi del genere.
Forse se posti un po' di codice e' meglio.
--
Andrea Laforgia - walkietalkie(at)
libero.it
#exclude <windows.h>

Tutto chiaro ?
Se non ho capito male, la sua necessita' e' quella di
evitare che un form contenente una dbgrid con dei dati
subisca l'effetto del doppio click impartito su un secondo
form (modale, al di sopra di esso), appena dopo aver cercato
delle informazioni e aver riempito la dbgrid superiore.
I form, cioe', sono entrambi gia' creati.
Puo' darsi sia cretino io, ma onestamente non capisco cosa
c'entri l'OnCreate.


c'entri l'OnCreate.
Sono convinto che tu non sia un cretino, e in effetti OnCreate non
c'entra direttamente con il problema che avevo posto: serviva comunque
a suggerire la possibilita' di disabilitare un event-handler, in
questo caso quello associato al click del dbgrid. Una soluzione forse
non elegante, ma comunque pur sempre una soluzione.
ciao, Michele

Forse se posti un po' di codice e' meglio.
Questa e' la procedura associata al pulsante di ricerca, che viene
premuto dall'utente quando vuole fare una ricerca dei codici degli
articoli:
procedure TFDistinta.BRicCodClick(Sender: TObject);
begin
  RicArticoli.StrDaCercare:=editcodiceart.text;
  RicArticoli.Ricerca:=trCodice;
  if RicArticoli.MostraRicerca then begin
    EditCodiceart.Text:=RicArticoli.Codice;
    EditSequenza.Text := IntToStr( Calcola_Sequenza_Massima );
    EditImpiego.Text := '0';
    EditCodiceArt.SetFocus;
  end;
end;
Come vedi si limita a chiamare la funziona MostraRicerca del
componente RicArticoli, e trasferire i risultati negli edit
corrispondenti (in questo caso nell EditCodice perche' era il pulsante
di ricerca associato al codice articolo).
La funzione MostraRicerca fa apparire una finestra di ricerca,
contenente un dbgrid con le righe degli articoli corrispondenti ai
criteri di ricerca impostati.
L'utente puo' o scegliere una riga del db grid corrispondente a un
articolo e quindi premere il pulsante di conferma (ModalResult=ok),
oppure fare un doppio clic su di essa, intercettato da una procedura
che richiama lo stesso pulsante di conferma.
Quello che accade e' questo: se l'utente preme il pulsante di conferma
tutto procede bene, se l'utente invece fa un doppio clic sul dbgrid
per selezionare un articolo, una volta che la procedura sopra
riportata ha finito l'esecuzione, passa il controllo all'event-handler
dell'evento OnClic di un *altro* dbgrid, quello della form sul quale
era stato premuto il pulsante di ricerca, event-handler che modifica
il codice dell'articolo selezionato, proprio come dovrebbe accadere se
l'utente avesse fatto un clic su una riga del dbgrid!
Notare che questo si verifica solo se il doppio-clic fatto nel dbgrid
della finestra di ricerca e' posizionato sopra un riga dell'altro
dbgrid, quello della form principale, form che al momento del doppio
clic e' pero' in secondo piano.
Ti riporto per completezza anche il codice della funzione
MostraRicerca associata al componente di ricerca:
Function TCmpRicArticoli.MostraRicerca: Boolean;
begin
  RicArt := TFrmRicArticoli.Create(Application);
  Result:=False;
  try
    with RicArt do begin
      RBScelta.ItemIndex:=Integer(Ricerca);
      CBComparatori.ItemIndex:=0;
      StrToSearch.Text:=StrDaCercare;
      QueryArticoli.close;
      QueryArticoli.active:=false;
      QueryArticoli.DataBaseName:=DatabaseName;
      CalcQuery;
      DBCodice.DataField:='Codice';
      DBDescrizione.DataField:='Descrizion';
      ShowModal;
      Result := (ModalResult = MrOk);
      Codice:=DBCodice.Text;
      Descrizione:=DBDescrizione.Text;
      Ricerca:=TipoRicerca(RBScelta.ItemIndex);
      QueryArticoli.active:=false;
      QueryArticoli.close;
 
    end;
  finally
    RicArt.Free;
  end;
ciao, Michele

dell'evento OnClic di un *altro* dbgrid, quello della form sul quale
Ok, ti dico invece come faccio io.
Il mio programma e' composto da una finestra principale,
dalla quale e' possibile accedere alla gestione dei
contratti.
La finestra di gestione dei contratti e' modale e ci sono in
alto i toolbutton con le diverse voci (Nuovo, Varia,
Cancella, Cerca, ecc..) e al di sotto la dbgrid contentente
tutti i contratti presenti (associata tramite apposita
datasource a sqlContratti, una TQuery).
Cliccando su "Cerca", si accede alla funzione di ricerca del
contratto (per Numero Contratto o per Nome e Cognome
lavoratore, o parte di questi ultimi).
In pratica si apre una nuova finestra modale, in cui e'
presente in alto un pannello contenente i campi edit che
costituiscono i parametri di ricerca e a fianco un bottone
"Trova".  
Al di sotto e' presente una dbgrid che conterra' i risultati
della ricerca (la dbgrid e' associata tramite apposita
datasource a sqlRicercaContratti, un'altra TQuery).
Alla pressione di "Trova" parte la query sqlRicercaContratti
che popola, quindi, la dbgrid.
Cliccando su "Ok" o facendo doppio click su una riga della
dbgrid la finestra si chiude restituendo al chiamante il
codice del contratto trovato (alla pressione di "Ok" lancio
l'event handler del doppio click, come hai fatto tu).
Non uso alcun componente, per intenderci, ho solo le due
finestre frmGestioneContratti e frmRicercaContratti.
frmRicercaContratti contiene il metodo :
function EseguiRicercaContratto(var CodContr : String) :
TModalResult ;
e la variabile privata "ContrattoTrovato" (che viene
valorizzata al doppio click sulla dbgrid dei contratti
trovati.
Il corpo di EseguiRicercaContratto e' :
begin
  Result := ShowModal ;
  CodContr := ContrattoTrovato ;
end ;
Nel mio caso funziona perfettamente.

Nel mio caso funziona perfettamente.
Ma, la cosa mi sembra sempre piu' misteriosa :-(
Grazie comunque, provero' a vedere se c'e' qualche stranezza nel
codice che mi e' sfuggita.
ciao, Michele

cambiare il risultato del tutto.
Prova a invertire questo meccanismo.
(Detto cosi', credo anch'io che sia ininfluente).
--
CyberWalkie - walkietalkie(at)
libero.it