Developpez.com - C
X

Choisissez d'abord la catégorieensuite la rubrique :



Création d'un composant C++ Builder

Par CGi

Le 24 juillet 2003


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)





Sommaire

1 - Création d'un composant pas à pas.
2 - Création d'un composant graphique.
3 - Propriété de type TStrings.
4 - Propriété de type TBitmap et contrôle du Owner.
5 - Propriété de type enum.
6 - Contrôle fenêtré.
7 - Evénement personnalisé et sous-propriétés.
8 - Composant pouvant interagir avec ses semblables.
9 - Ressources dans un composant.
10 - Boîte de dialogue dans un composant.
11 - Composant conteneur.
12 - Les éditeurs de composants. Nouveau



C/C++
  Les pointeurs du C/C++.   Les listes chaînées.             Liste simple.             Liste triée.             Liste double.   Les arbres.   Les tas.   Le C orienté objets ?

  1 - La fenêtre principale.   2 - Contrôles et messages.   3 - Les commandes.   4 - Dialogue std.   5 - Contexte de périph.   6 - Dessiner.   7 - Les ressources.   8 - Dialogue perso.   9 - Dialogue comm.   10 - Les accélérateurs.

Assembleur
  Assembleur sous Visual C++.

C++ BUILDER
  Trucs et astuces.   Composant.   TRichEdit.   TDrawGrid.   Application MDI.   TThread.   wxWidgets.   Style Win XP.

  Première application.   Construire un menu.   Dessiner.   Sisers, Timers...   Dialogues standards.   Dialogues perso.

DotNet
  Composant C# Builder.   Contrôle WinForm.   Application MDI.

Java
  Applet java.





Copyright 2002-2016 CGi - Tous droits réservés CGi. Toutes reproduction, utilisation ou diffusion de ce document par quelque moyen que ce soit autre que pour un usage personnel doit faire l'objet d'une autorisation écrite de la part de l'auteur, propriétaire des droits intellectuels.
Les codes sources de ce document sont fournis en l'état. L'utilisateur les utilise à ses risques et périls, sans garantie d'aucune sorte de la part de l'auteur. L'auteur n'est responsable d'aucun dommage subi par l'utilisateur pouvant résulter de l'utilisation ou de la distribution des codes sources de ce document.
De la même façon, l'auteur n'est en aucun cas responsable d'une quelconque perte de revenus ou de profits, ou de données, ou de tous dommages directs ou indirects, susceptibles de survenir du fait de l'utilisation des codes sources de ce document, quand bien même l'auteur aurait été averti de la possibilité de tels dommages. L'utilisation des codes sources de ce document vaut acceptation par l'utilisateur des termes de la licence ci-dessus.

Contacter le responsable de la rubrique C