4 - Composant avec une propriété de type TBitmap et contrôlant la fiche qui le possède :
Nous allons voir comment inclure une propriété de type TBitmap dans un composant,
le principe est un peu le même que le TLabelIndice du chapitre 3. L'aide de C++ Builder
n'est pas plus commentée que pour le TStrings. Ce composant sera aussi capable d'agir
sur la Fiche qui le possède.
Pour l'exemple nous allons faire un composant simple auquel on ajoutera une seule
propriété : de type TBitmap bien sûr. Il descendra de TComponent, donc ce sera
un composant non visuel. Les composants non visuels descendent en principe directement
de TComponent. Vous allez me dire pourquoi faire un composant avec une
image qui est invisible. Et bien en fait il va tapisser la fiche qui le possède,
avec l'image que vous aurez mis dans la propriété Image du composant.

Je me suis inspiré du "Trucs & Astuces"
Tapisser une Form avec un Bitmap pour faire ce composant.
Fichier "tapisseur.h" :
#ifndef TapisseurH
#define TapisseurH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Graphics.hpp> // rajouté pour TBitmap
#include <Forms.hpp> // rajouté pour TForm
//---------------------------------------------------------------------------
class PACKAGE TTapisseur : public TComponent
{
private:
Graphics::TBitmap *FImage;
TForm * LaForm;
protected:
virtual void __fastcall SetImage(Graphics::TBitmap *AImage);
virtual Graphics::TBitmap* __fastcall GetImage();
virtual void __fastcall Paint(TObject *Sender);
virtual void __fastcall BitmapChanged(TObject *Sender);
public:
__fastcall TTapisseur(TComponent* Owner);
virtual __fastcall ~TTapisseur();
__published:
__property Graphics::TBitmap *Image = {read=GetImage, write=SetImage};
};
//---------------------------------------------------------------------------
#endif
Dans le fichier en-tête "tapisseur.h" section private nous déclarons le pointeur
sur notre image de type TBitmap, puis un pointeur sur une TForm qui nous servira
à pointer sur la Form qui contiendra notre composant.
Dans la section protected nous déclarons les méthodes SetImage et GetImage appelées
par les méthodes write et read de la propriété Image.
La méthode Paint qui sera appellée par l'événement OnPaint de la fiche qui
contient notre composant. Elle sera donc capable de dessiner sur cette fiche. Puis la méthode
BitmapChanged qui sera appelée si le Bitmap a changé.
Dans la section __published, notre propriété Image, selon le même principe qu'au chapitre
précédent.
Fichier "tapisseur.cpp"
#include <basepch.h>
#pragma hdrstop
#include "Tapisseur.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck est utilisé pour vérifier que les composants créés n'ont
// aucune fonction virtuelle pure.
static inline void ValidCtrCheck(TTapisseur *)
{
new TTapisseur(NULL);
}
//---------------------------------------------------------------------------
__fastcall TTapisseur::TTapisseur(TComponent* Owner)
: TComponent(Owner)
{
FImage = new Graphics::TBitmap();
LaForm = (TForm *)Owner;
LaForm->OnPaint = Paint;
FImage->OnChange = BitmapChanged ;
}
//---------------------------------------------------------------------------
__fastcall TTapisseur::~TTapisseur()
{
delete FImage;
}
//---------------------------------------------------------------------------
void __fastcall TTapisseur::Paint(TObject *Sender)
{
if(!FImage->Empty)
for(int x=0 ; x < LaForm->Width ; x+=FImage->Width)
{
for (int y=0 ; y < LaForm->Height ; y+=FImage->Height)
LaForm->Canvas->Draw(x,y,FImage);
}
}
//---------------------------------------------------------------------------
void __fastcall TTapisseur::SetImage(Graphics::TBitmap *AImage)
{
FImage->Assign(AImage);
}
//---------------------------------------------------------------------------
Graphics::TBitmap* __fastcall TTapisseur::GetImage()
{
return FImage;
}
//---------------------------------------------------------------------------
void __fastcall TTapisseur::BitmapChanged(TObject *Sender)
{
LaForm->Invalidate();
}
//---------------------------------------------------------------------------
namespace Tapisseur
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TTapisseur)};
RegisterComponents("MesCompo", classes, 0);
}
}
Passons maintenant à la definition de nos méthodes :
dans le constructeur nous créons l'objet TBitmap, nous récupérons l'adresse de la Form
propriétaire de notre composant pour l'affecter à notre pointeur sur TForm.
Le propriétaire étant reçu par le paramètre Owner du constructeur de notre composant.
Tout composant descendant de TComponent à un Owner (Propriétaire) qui peut éventuellement être NULL.
Et nous affectons la méthode Paint de notre composant à l'événement OnPaint de la
Form auquel il appartient. De même nous affectons la méthode BitmapChanged à l'événement OnChange du
Bitmap.
Destruction de notre objet TBitmap dans le destructeur.
La méthode Paint utilise le Canvas de la Form pour dessiner. Nous testons que le Bitmap n'est pas vide
avant de dessiner.
Pour les méthodes SetImage et GetImage, c'est le même principe dans l'exemple
du chapitre 3.
La méthode BitmapChanged nous serre donc à rafraîchir l'affichage de la fiche en appelant
sa méthode Invalidate.
Utilisation de TTapisseur :
Posez un TTapisseur (Tapisseur1) sur la Fiche (Form1), affectez une image à sa propriété Image par
l'intermédiaire de l'inspecteur d'objets, exécutez et c'est tout. (L'image ne s'affiche qu'a l'exécution.)
CGi
Avec la contribution d'Alacazam pour la relecture.
Télécharger les sources.
(Est inclus le fichier "tapisseur.dcr" contenant l'icône qui le représente
sur la palette de composants)
|