Newsgroup: it.comp.lang.delphi
Titolo: TNotifyEvent

Ho bisogno di conoscere quando un record cambia (FDQuery1.AfterScroll)
 
Imposto FMyEvent e
su Form1 clDataModule.OnMyEvent := ChangeRecord; //Assegna TNotifyEvent
che dovrebbe scattare ad ogni AfterScroll
 
complila, ma l'evento non scatta.
 
dove ho sbagliato ?
 
/////////////
DataModule1 = class(TDataModule)
 
   private
     { Private declarations }
     FMyEvent: TNotifyEvent;
 
   private
 
   published
     property OnMyEvent: TNotifyEvent read FMyEvent write FMyEvent;
 
function TDataModule.ChangeRecord: boolean;
begin
  Result := true;
end;
 
procedure TDataModule.FDQuery1AfterScroll(DataSet: TDataSet);
begin
  ChangeRecord;
end;
 
/////
Form1 = class(TForm)
...
   private
     clDataModule : TDataModule2;
     procedure ChangeRecord(Sender: TObject);
 
procedure Form1.FormCreate(Sender: TObject);
begin
   clDataModule := TDataModule.Create(self);
   clDataModule.OnMyEvent := ChangeRecord; //Assegna TNotifyEvent
end;
 
procedure Form1.ChangeRecord(Sender: TObject);
begin
  ShowMessage('changed');
end

>
Perche' mi serve ?
un DbGrid sul Form, carica un Blob e lo visualizza, inoltre carica su un 
TImage.
 
Tutto regolare fino a che si scorre con la rotella, ma se clicco su una 
riga qualunque del DbGrid visualizza il Blob del record precedente.
 
procedure Tfrm_Lingue.grdAviableLangDrawColumnCell(Sender: TObject; 
const Rect: TRect;
   DataCol: Integer; Column: TColumn; State: TGridDrawState);
var Image, Image1: TPngImage;
     MemStream, MemStream1: TMemoryStream;
 
....
 
Naturalmente posso usare l'evento della FDQuery, ma dovrei rimandare 
ancora al DataModule per eventuali controlli, l'intenzione sarebbre 
evitare questo pasaggio.
 
type
   Tfrm_Lingue = class(TForm)
 
   private
     procedure ChangeRecord(Sender: TDataSet);
....
 
procedure Tfrm_Lingue.FormCreate(Sender: TObject);
begin
   clData_Language.Qry_AllLanguage.AfterScroll := ChangeRecord;
   ...
end;
 
procedure Tfrm_Lingue.ChangeRecord(Sender: TDataSet);
begin
  ShowMessage('changed');
end;

..non è che il tuo datamodule è in autocreate e che i tuoi componenti visuali sono collegati ai dataset del datamodule in autocreate e non a quello che tu crei in modo esplicito al create della form..?
 
A.


certo che no , il Datamodule e' creato a runtime ed istanziato.
 
per lo scoordinamento tra DbGrid e record corrente, ho risolto in modo 
semplice, indirizzzando il caricamento del Blob nell'evento OnCellClick
del DbGrid.
 
procedure Tfrm_Lingue.grdAviableLangCellClick(Column: TColumn);
begin
   LoadImage;
 

 dove ho sbagliato ?
 
Guardando il poco codice che hai messo, mi sembra che da
nessuna parte il tuo evento venga fatto scattare, da qualche
parte (dentro a Changerecord ?)  dovrebbe esserci un:
 
  if assigned(fMyEvent) then fMyEvent(self);
 
 
ciao
Giacomo


>
per capire con un esempio: imposto e assegno MyEvent
dubbio : cosa dovrebbe fare scattare MyEvent ?
MyEvent indica che dovrà andare nella procedure ChangeRecord a fare 
qualcosa, ma non c'è un evento di sistema tipo <control>.OnClick
 
 
type
   Tfrm_Lingue = class(TForm)
 
   private
     FMyEvent: TNotifyEvent;
     procedure ChangeRecord(Sender: TObject);
 
   public
 
     property MyEvent: TNotifyEvent read FMyEvent write FMyEvent;
 
...
 
procedure Tfrm_Lingue.FormCreate(Sender: TObject);
begin
   if Assigned(MyEvent) then MyEvent(self);
   MyEvent := nil;
   MyEvent := ChangeRecord; //assegna evento a procedure
end;
 
procedure Tfrm_Lingue.ChangeRecord(Sender: TObject);
var IdRif: integer;
begin
  ...
 
end;
 
sicuramente manca qualcosa
ciao
Stefano


Direi che manca proprio il momento in cui viene fatto scattare
l'evento: tu definisci un nuovo evento, agganci all'evento
una procedura che viene eseguita quando l'evento scatta ma
non vedo codice che lo fa scattare (lo fai nel FormCreate
quando ancora l'evento e' sicuramente nil e non ha una
procedura associata)
 
Se guardi nel sorgente della VCL vedi che l'onClick e' un
evento a cui TU puoi agganciare codice ma e' la VCL che
fa scattare l'evento (in risposta al messaggio di windows
ma non solo)
 
Nel tuo codice se definisci un nuovo evento devi preoccupari
anche di farlo scattare al momento giusto. Questo momento puoì
anche essere in risposta ad altri eventi della VCL (cioe'
dentro a un metodo agganciato a "Query.OnChangeRecord" se vuoi)
 
ciao
Giacomo
 

Ciao Stefano,
  quello che intendeva Giacomo (forse) e' questo
 
function TDataModule.ChangeRecord: boolean;
begin
  Result := true;
end;
 
procedure TDataModule.FDQuery1AfterScroll(DataSet: TDataSet);
begin
  If ChangeRecord then
  begin
      if Assigned(MyEvent) then MyEvent(self); //
   end;
end;
 
Sei tu che sai cosa fa MyEvent, quindi sei tu che sai dove mettere la 
chiamata per questo evento (quello sopra e' giusto un esempio).
 
Ciao
 
Daniele
 


era proprio l'attivazione dell'evento che mancava, la facevo nel 
OnCreate e non serviva.
 
con il vostro aiuto ho capito come fare.
 
nel OnCreate del form
<dataModule>.OnMyEvent := <procedure evento>;
 
nel datamodule dove serve attivo l'evento che scatta e riporta a 
<procedure evento> nel Form
 
procedure/function voluta
begin
  if Assigned(OnMyEvent) then OnMyEvent(Self); //activate event
end;
 
grazie delle indicazioni.