5.5 NOTICE METHODOLOGIQUE
construire un nouvel événement


Code pratique : une pile Lifo événementielle



Objectif : Nous proposons ici en suivant pas à pas l'enrichissement du code de montrer comment implanter un nouvel événement nommé OnTruc dans une classe dénotée ClassA. Puis nous appliquerons cette démarche à une pile Lifo qui sera rendu sensible à l'empilement et au dépilement, par adjonction de deux événements à la classe.

Pour construire un nouvel événement dans ClassA :

 
Version-1 du code source

Unit  UDesignEvent  ;
 
 interface
 type
  
EventTruc  procedure  ( Sender: TObject info :string of  object  ;
  
  
ClassA  class
 private
  
FOnTruc  EventTruc  ;
 public
  
OnTruc  EventTruc  read  FOnTruc   write  FOnTruc  ;
end;

implementation
 
 
end.


 
Lorsque l'événement se nomme OnXXX, les équipes de développement Borland donnent la fin du nom de l'événement OnXXX à la procédure redéfinissable. Ici  pour l'événement OnTruc à la place de DeclencheTruc, nous la nommerons Truc.

Version-2 du code source

Unit  UDesignEvent  ;
 
 interface
 type
  
EventTruc  procedure  ( Sender: TObject info :string of  object  ;
  
ClassA  class
 private
  
FOnTruc  EventTruc  ;
 protected
  procedure 
Truc(s :string ) ; virtual // surchargeable dynamiquement
 
public
  
OnTruc  EventTruc  read  FOnTruc   write  FOnTruc  ;
end;

implementation
 
 procedure 
ClassA.Truc(s :string ) ;
 begin
  if 
Assigned ( FOnTruc )  then
   
FOnTruc ( self  , s)
 
end;
 
end.



Nous définissons une classe ClasseUse qui utilise sur un objet de classe ClassA l'événement OnTruc.

 

Version-3 du code source

Unit  UDesignEvent  ;
 
 interface
 type   
EventTruc  procedure  ( Sender: TObject info :string of  object  ;
  
  
ClassA  class
 private
  
FOnTruc  EventTruc  ;
 protected
  procedure 
Truc(s :string ) ; virtual // surchargeable dynamiquement
 
public
  
ObjA  ClassA  ;
  
OnTruc  EventTruc  read  FOnTruc   write  FOnTruc  ;
  procedure 
LancerTruc // Declenche l'événement OnTruc
end;

ClasseUse  class
 public
  procedure 
method_100( Sender: TObject info :string ) ;
  procedure 
method_101( Sender: TObject info :string ) ;
  procedure 
method_102( Sender: TObject info :string ) ;
  procedure 
method_103( Sender: TObject info :string ) ;
  procedure 
principale ;
end;

implementation
 
 
{-------------------  ClassA   ------------------------}
 
procedure  ClassA.Truc(s :string ) ;
 begin
  if 
Assigned ( FOnTruc )  then
   
FOnTruc ( self  , s)
 
end;
 
 procedure 
ClassA.LancerTruc  ;
 begin
  
....
  Truc ("événement déclenché")
;
  
....
 
end;
 
{-------------------  ClasseUse   ------------------------}
 
procedure  ClasseUse.principale ;
 begin
  
//....
  
ObjA  :=  ClassA.Create  ;
  
ObjA.OnTruc  :=  method_102  // connexion
  //....
  
ObjA.LancerTruc  // lancement
 
end;
 
 procedure 
ClasseUse.method_100( Sender: TObject info :string ) ;
 begin
  
//....
 
end;
 
 procedure 
ClasseUse.method_101( Sender: TObject info :string ) ;
 begin
  
//....
 
end;
 
 procedure 
ClasseUse.method_102( Sender: TObject info :string ) ;
 begin
  
//....
 
end;
 
 procedure 
ClasseUse.method_103( Sender: TObject info :string ) ;
 begin
  
//....
 
end;
 
end.

 


Code pratique : une pile Lifo événementielle

Objectif : Nous livrons une classe de pile lifo héritant d'une Tlist (Un objet Tlist de Delphi, stocke un tableau de pointeurs, utilisé ici pour gérer une liste d'objets) et qui est réactive à l'empilement et au dépilement d'un objet. Nous suivons la démarche précédente en nous inspirant de son code final pour construire deux événements dans la pile lifo et lui permettre de réagir à ces deux événements.


unit   ULifoEvent  ;
 
 interface
 uses  
classes,Dialogs  ;
  
 type
  
DelegateLifo  procedure  Sender TObject  ;   :string  of   object  ;
  
  
ClassLifo  class  (TList)
 
private
  
FOnEmpiler  DelegateLifo  ;
  
FOnDepiler  DelegateLifo  ;
 public
  function  
Est_Vide   boolean  ;
  procedure  
Empiler (elt  string  ;
  procedure  
Depiler (  var   elt  string  ;
   property  
OnEmpiler  DelegateLifo   read   FOnEmpiler   write   FOnEmpiler  ;
   property  
OnDepiler  DelegateLifo   read   FOnDepiler   write   FOnDepiler  ;
end;

ClassUseLifo  class
 public
  procedure  
EmpilerListener(  Sender TObject  ;   :string  ;
  procedure  
DepilerListener(  Sender TObject  ;   :string  ;
  constructor  
Create  ;
  procedure  
main  ;
end;

implementation
 
 procedure  
ClassLifo.Depiler(  var   elt  string  ;
 begin
  if  
not   Est_Vide   then
  begin
   
elt  :=string  (self.First)  ;
   
self.Delete(0)  ;
   
self.Pack  ;
   
self.Capacity  :=  self.Count  ;
   if  
assigned(FOnDepiler)   then
    
FOnDepiler (  self  ,elt )
  
end
 end;
 
 procedure  
ClassLifo.Empiler(elt  string  ;
 begin
  
self.Insert(0 , PChar(elt))  ;
  if  
assigned(FOnEmpiler)   then
   
FOnEmpiler (  self  ,elt )
 
end;
 
 
 function  
ClassLifo.Est_Vide  boolean  ;
 begin
  result 
:=   self.Count  ;
 end;
 
 
{ ClassUseLifo }
 
 
constructor   ClassUseLifo.Create  ;
 begin
  inherited;
 end;
 
 procedure  
ClassUseLifo.DepilerListener(  Sender:   TObject  ;   :string  ;
 begin
  
writeln  'On a depile : '  ,s)  ;
 end;
 
 procedure  
ClassUseLifo.EmpilerListener(  Sender:   TObject  ;   :string  ;
 begin
  
writeln  'On a empile : '  ,s)  ;
 end;
 
 procedure  
ClassUseLifo.main  ;
 var
  
pileLifo  ClassLifo  ;
  
ch  :string  ;
  begin
   
pileLifo  :=  ClassLifo.Create  ;
   
pileLifo.OnEmpiler  :=   EmpilerListener  ;
   
pileLifo.OnDepiler  :=   DepilerListener  ;
   
pileLifo.Empiler(  '[ eau ]'  ;
   
pileLifo.Empiler(  '[ terre ]'  ;
   
pileLifo.Empiler(  '[ mer ]'  ;
   
pileLifo.Empiler(  '[ voiture ]'  ;
   
writeln  'Depilement de la pile :'  ;
   while  
not   pileLifo.Est_Vide   do
   begin
    
pileLifo.Depiler(ch)  ;
    
writeln  (ch)  ;
   end;
   
writeln  'Fin du depilement.'  ;
   
readln  ;
  end;
  
end.