Il linguaggio di programmazione Delphi
 

TNotifyEvent

Stefano 5 Feb 2017 19:20
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
Stefano 5 Feb 2017 20:36
Il 05/02/2017 19:20, Stefano ha scritto:
>> 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 ?
>>
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;
Alberto Salvati 6 Feb 2017 09:03
..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.
Stefano 6 Feb 2017 10:17
Il 06/02/2017 09:03, Alberto Salvati ha scritto:
>> ..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;
Giacomo Degli Esposti 6 Feb 2017 12:09
On Sunday, February 5, 2017 at 7:20:31 PM UTC+1, Stefano wrote:
> 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.

Come fai a capire che non scatta? Guardando la messagebox o
attraverso il debugger, mettendo dei breakpoint ?

> 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

> /////////////
> 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
Stefano 6 Feb 2017 14:28
Il 06/02/2017 12:09, Giacomo Degli Esposti ha scritto:
> On Sunday, February 5, 2017 at 7:20:31 PM UTC+1, Stefano wrote:
>> [...]
>> Come fai a capire che non scatta? Guardando la messagebox o
>> attraverso il debugger, mettendo dei breakpoint ?
>>
>>> 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);
>>
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
Giacomo Degli Esposti 6 Feb 2017 15:09
On Monday, February 6, 2017 at 2:28:20 PM UTC+1, Stefano wrote:
> Il 06/02/2017 12:09, Giacomo Degli Esposti ha scritto:
>> On Sunday, February 5, 2017 at 7:20:31 PM UTC+1, Stefano wrote:
>>> [...]
>>> Come fai a capire che non scatta? Guardando la messagebox o
>>> attraverso il debugger, mettendo dei breakpoint ?
>>>
>>>> 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);
>>>
> 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

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
Daniele 6 Feb 2017 15:38
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
Stefano 6 Feb 2017 18:18
Il 06/02/2017 15:38, Daniele ha scritto:
>> 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.

Links
Giochi online
Dizionario sinonimi
Leggi e codici
Ricette
Testi
Webmatica
Hosting gratis
   
 

Il linguaggio di programmazione Delphi | Tutti i gruppi | it.comp.lang.delphi | Notizie e discussioni delphi | Delphi Mobile | Servizio di consultazione news.