Create Component : TImage ne s'affiche pas

Résolu
tuss Messages postés 9 Date d'inscription mardi 10 octobre 2006 Statut Membre Dernière intervention 20 décembre 2013 - Modifié par tuss le 20/12/2013 à 23:06
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 - 23 déc. 2013 à 10:26
Bonjour à Tous...

J'ai créé un composant TSprite, dérivé de TImage encapsulant un TTimer, avec une propriété ImageList pour y stocker des images.

Je pose sur mon formulaire, mon composant Sprite1. (pas d'erreur)
Je pose sur ce même formulaire un composant ImageListe1 chargé avec des images.
Je fait pointer la propriété ImageList de mon composant Spite1 sur ImageListe1. (pas d'erreur)
Je met en route mon composant Sripte avec sa propriété Active (Timer.enabled...) (pas d'erreur)
Mais mon composant Sprite(TImage) reste vide, rien ne se dessine. Par défaut il devrait m'afficher la première image du ImageList1.
Mon Composant fontionne, car si je regarde sa propriété Picture elle se met bien à jour et les image change.
Pourquoi mon composant Sprite(TImage) n'affiche rien ?.
Voici mon code :

unit Sprite;
//############################################################################
interface
//############################################################################
uses
SysUtils,Windows,Messages, Classes,Graphics,Controls, ExtCtrls, ThreadComponent;
//############################################################################
type
TSprite = class(TImage)
private
Animation: TTimer;
FImageList: TImageList;
FInterval: cardinal;
FActive: boolean;
NumImage: integer;
procedure SetImageList(Valeur:TImageList);
procedure SetInterval(Valeur:cardinal);
procedure SetActive(Valeur:boolean);
//############################################################################
protected
procedure Paint; override;
Procedure SetAnimation(Sender:TObject);
//############################################################################
public
constructor Create(AOwner: TComponent); override;
destructor Destroy;override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
//############################################################################
published
property ImageList:TImageList read FImageList write SetImageList;
property Interval:cardinal read FInterval write SetInterval;
property Active:boolean read FActive write SetActive;
end;
//############################################################################
procedure Register;
//############################################################################
implementation
//############################################################################
constructor TSprite.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
//Doublebuffered:=true;
FImageList:= nil;
Picture:=nil;
FInterval:=1000;
Animation:=TTimer.Create(Self);
Animation.OnTimer:=SetAnimation;
Animation.Interval:=FInterval;
Animation.enabled:=false;
NumImage:=0;
end;
//############################################################################
destructor TSprite.Destroy;
begin
if Assigned(FImageList) then
FImageList.RemoveFreeNotification(Self);
Animation.Free;
inherited;
end;
//############################################################################
procedure TSprite.Notification(AComponent: TComponent; Operation: TOperation);
begin
if (aComponent = FImageList) and (Operation = opRemove) then
FImageList:= nil
else
inherited Notification(AComponent, Operation);
end;
//############################################################################
procedure TSprite.SetAnimation;
begin
NumImage:=NumImage+1;
if NumImage=FImageList.count-1 then NumImage:=0;
Invalidate;
end;
//############################################################################
procedure TSprite.SetImageList(Valeur:TImageList);
begin
if Valeur <> FImageList then
begin
if Assigned(FImageList) then
FImageList.RemoveFreeNotification(Self);

FImageList:= Valeur;
if Assigned(FImageList) then
begin
FImageList.FreeNotification(Self);
Update;
invalidate;
end;
end;
end;
//############################################################################
procedure TSprite.SetInterval(Valeur: cardinal);
begin
if FInterval <> Valeur then
begin
FInterval:= Valeur;
Update;
invalidate;
end;
end;
//############################################################################
procedure TSprite.SetActive(Valeur: boolean);
begin
if FActive <> Valeur then
begin
FActive:= Valeur;
Update;
invalidate;
Animation.enabled:=FActive;
end;
end;
//############################################################################
procedure TSprite.Paint;
begin
if Assigned(FImageList) then
FImageList.GetBitmap(NumImage,Picture.Bitmap);
end;
//############################################################################
procedure Register;
begin
RegisterComponents('MesCompo', [TSprite]);
end;
//############################################################################
end.

Merci à Tous et bonnes fêtes de fin d'année...

1 réponse

sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
23 déc. 2013 à 10:26
Salut,

Je te propose les quelques corrections ci dessous. Attention, il reste un peu de travail (notamment sur le Create)

unit Sprite;
//############################################################################
interface
//############################################################################
uses
 SysUtils,Windows,Messages, Classes,Graphics,Controls, ExtCtrls; // unité inutilisée : ThreadComponent;
//############################################################################
type
  TSprite = class(TImage)
  private
   Animation: TTimer;
   FImageList: TImageList;
   FInterval: cardinal;
   FActive: boolean;
   NumImage: integer;   
   procedure SetImageList(Valeur:TImageList);
   procedure SetInterval(Valeur:cardinal);
   procedure SetActive(Valeur:boolean);
//############################################################################
  protected
{
   procedure Paint; override;

   Suppression de la surcharge de la méthode Paint car, selon l'aide de Delphi :
   "Telle qu'implémentée dans TGraphicControl, Paint ne fait rien."
   Et relocalisation du code d'affichage dans le déclenchement du timer
}
   Procedure SetAnimation(Sender:TObject);
//############################################################################
  public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy;override;
   procedure Notification(AComponent: TComponent; Operation: TOperation); override;
//############################################################################
  published
   property ImageList:TImageList read FImageList write SetImageList;
   property Interval:cardinal read FInterval write SetInterval;
   property Active:boolean read FActive write SetActive;
end;
//############################################################################
procedure Register;
//############################################################################
implementation
//############################################################################
constructor TSprite.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 //Doublebuffered:=true;

{
 Il faut indiquer au composant le composant parent.
 Ici je fais un cast un peu brutal... Il faut que tu gères ça
 plus proprement et vérifier si le cast peut passer...
}
 Parent := TWinControl(AOwner);

 FImageList:= nil;
 Picture:=nil;
 FInterval:=1000;
 Animation:=TTimer.Create(Self);
 Animation.OnTimer:=SetAnimation;
 Animation.Interval:=FInterval;
 Animation.enabled:=false;
 NumImage:=0;
end;
//############################################################################
destructor TSprite.Destroy;
begin
 if Assigned(FImageList) then
  FImageList.RemoveFreeNotification(Self);
 Animation.Free;
 inherited;
end;
//############################################################################
procedure TSprite.Notification(AComponent: TComponent; Operation: TOperation);
begin
 if (aComponent = FImageList) and (Operation = opRemove) then
  FImageList:= nil
   else
    inherited Notification(AComponent, Operation);
end;
//############################################################################
procedure TSprite.SetAnimation;
var
{
Assez bizarre, je ne me l'explique pas...
Si on ne passe pas par un bitmap temporaire mais qu'on fait directement :
FImageList.GetBitmap(NumImage, Picture.Bitmap);
Une fois arrivé à la dernière image de l'imagelist, le composant reste
bloqué sur la dernière image qu'il affiche en boucle, alors que le 'NumImage'
varie bien...

}
   myBitmap : TBitmap;
begin
 Animation.Enabled := False;
 NumImage:=NumImage+1;
 if NumImage=FImageList.count-1 then NumImage:=0;
 myBitmap := TBitmap.Create;
 FImageList.GetBitmap(NumImage, myBitmap);
 Picture.Bitmap := myBitmap;
 myBitmap.Free;
 Invalidate;
 Animation.Enabled := True;
end;
//############################################################################
procedure TSprite.SetImageList(Valeur:TImageList);
begin
 if Valeur <> FImageList then
  begin
   if Assigned(FImageList) then
    FImageList.RemoveFreeNotification(Self);

   FImageList:= Valeur;
   if Assigned(FImageList) then
    begin
     FImageList.FreeNotification(Self);
     Update;
     invalidate;
    end;
  end;
end;
//############################################################################
procedure TSprite.SetInterval(Valeur: cardinal);
begin
 if FInterval <> Valeur then
  begin
   FInterval:= Valeur;
{
   Ici, il faut définir le nouvel intervalle du timer... Sinon, tu restes sur les 1000 millisecondes de ton create...
}
   Animation.Interval := FInterval;
   Update;
   invalidate;
  end;
end;
//############################################################################
procedure TSprite.SetActive(Valeur: boolean);
begin
 if FActive <> Valeur then
  begin
   FActive:= Valeur;
   Update;
   invalidate;
   Animation.enabled:=FActive;
  end;
end;
//############################################################################
procedure Register;
begin
 RegisterComponents('MesCompo', [TSprite]);
end;
//############################################################################
end.

0
Rejoignez-nous