unit WGK2Example;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
TObserver = class(TInterfacedObject, IFPObserver)
protected
fActiveObject: TObject;
public
constructor Create(anActiveobject: TObject);
destructor Destroy; override;
Procedure FPOObservedChanged(aSender: TObject; Operation: TFPObservedOperation; Data: Pointer); virtual;
property ActiveObject: TObject read fActiveObject write fActiveObject;
end;
TObserved = class(TInterfacedObject, IFPObserved)
private
fObservers: TFPList;
protected
fSubject: TObject;
public
constructor Create(aSubject: TObject); //The Form i want to monitor
destructor Destroy; override;
procedure FPOAttachObserver(AObserver: TObject);
procedure FPODetachObserver(AOBserver: TObject);
procedure FPONotifyObservers(ASender: TObject; AOperation: TFPObservedOperation; Data: Pointer);
property Subject: TForm read fSubject write fSubject;
property Observers: TFPList read fObservers write fObservers;
end;
{ TForm2 }
TForm2 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
procedure EditChange(Sender: TObject);
procedure FormShow(Sender: TObject);
private
public
Form2Observer: TObserver;
Form2Observed: TObserved;
end;
var
Form2: TForm2;
implementation
{$R *.lfm}
{ TForm2 }
procedure TForm2.FormShow(Sender: TObject);
begin
Form2Observed:= TObserved.Create(Form2);
Form2Observed.FPOAttachObserver(TObserver.Create(Edit1));
Form2Observed.FPOAttachObserver(TObserver.Create(Edit2));
Form2Observed.FPOAttachObserver(TObserver.Create(Edit3));
Form2Observed.FPOAttachObserver(TObserver.Create(Edit4));
end;
procedure TForm2.EditChange(Sender: TObject);
begin
if Sender.Equals(Edit1) then begin
//what do i do Here ??
Form2Observed.FPONotifyObservers({What should be here ?} , ooChange, Pointer(Edit1.Text));
end
else if Sender.Equals(Edit2) then
Form2Observed.FPONotifyObservers({What should be here ?} , ooChange, Pointer(Edit2.Text));
end;
{ *** TObserver *** }
constructor TObserver.Create(anActiveobject: TObject);
begin
inherited Create;
fActiveObject:= anActiveobject; { assign the working object }
end;
destructor TObserver.Destroy;
begin
fActiveObject:= nil; { release the link }
inherited Destroy;
end;
procedure TObserver.FPOObservedChanged(aSender: TObject;Operation: TFPObservedOperation;Data: Pointer);
begin
case Operation of
ooChange: begin
//Shouldn't be my Sender the Control ? or is it the Observerd Object ?
//Do i have to assign my Values, which are Sended, all manually to my Data ? (Something like MyDataCLass.Integer1:= TEdit(Sender).Text.ToInteger)
IF aSender is TEdit then begin;
IF TEdit(aSender).Equals(Form2.Edit1) then begin
Form2.Edit3.text:= TEdit(aSender).Text;
end else if TEdit(aSender).Equals(Form2.Edit2) then begin
Form2.Edit4.text:= TEdit(aSender).Text;
end else if TEdit(aSender).Equals(Form2.Edit3) then begin
Form2.Edit1.text:= TEdit(aSender).Text;
end else if TEdit(aSender).Equals(Form2.Edit4) then begin
Form2.Edit2.text:= TEdit(aSender).Text;
end;
end;
end;
ooFree: begin
(ASender as IFPObserved).FPODetachObserver(self);
end;
end;
{Case aSender.ClassName of
Form2: begin
ShowMessage(String(Data));
end;
end;}
end;
{ *** TObserved *** }
constructor TObserved.Create(aSubject: TObject);
begin
inherited Create;
fSubject:= aSubject; { just typecast to say, a TEdit, or your own creation :-) }
fObservers:= nil;
// ???
end;
destructor TObserved.Destroy;
begin
fSubject:= nil;
if assigned(fObservers) then begin
FPONotifyObservers(Self,ooFree,nil);
FreeAndNil(fObservers);
end;
inherited Destroy;
end;
procedure TObserved.FPOAttachObserver(aObserver: TObject);
begin
if not assigned(fObservers) then fObservers:= TFPList.Create; { lazy creation }
fObservers.Add(pointer(aObserver));
end;
procedure TObserved.FPODetachObserver(aObserver: TObject);
begin
if assigned(fObservers) then begin
fObservers.Remove(pointer(aObserver));
if (fObservers.Count = 0) then FreeAndNil(fObservers);
end;
end;
{ notify each observer in the list of observers, aSender is the subject, NOT Self }
procedure TObserved.FPONotifyObservers(ASender : TObject; AOperation : TFPObservedOperation; Data : Pointer);
var
I: integer;
Obs: TObserver;
begin
if assigned(fObservers) then begin
for I:= fObservers.Count-1 downto 0 do begin
Obs:= TObserver(fObservers[I]);
Obs.FPOObservedChanged(fSubject,aOperation,Data);
Obs:= nil;
end;
end;
end;
end.