Problème d'implémentation d'un nouveau composant - Erreur "Access Violation"
Bonjour à tous,
Je travaille sous C++ Builder 6, et je crée des nouveaux composants que j'essaie d'implémenter dans des projets de test.
Mais je bute sur la mise en service de l'un d'entre eux appelé TLabelConversionNombre, dont le but est d'afficher dans un TCustomLabel amélioré des nombres avec des préfixes d'unité, tout en pouvant utiliser une TStringList intégrée dans le composant. Pour ce dernier point mon code est adapté du tutoriel de CGI disponible à l'adresse :
http://chgi.developpez.com/compo3/
La seule chose importante que je pense avoir changé, c'est le fait de rendre les méthodes du composant publiques pour pouvoir les tester dans un projet
Quand j'ajoute mon composant au projet ITest_04, il me le compile sans aucune erreur, et me l'ajoute même dans ma palette de composants persos, prêt à être utilisé. Donc j'ai pu avoir l'impression que tout était bon.
Sauf que quand j'essaie de poser mon composant sur une Form, il apparait le message d'erreur suivant :
"Access violation at address 05DF2C5C in module 'ITest_04.bpl'. Read of address 00000000."
Et je ne comprends absolument pas pourquoi !!
J'ai cherché dans ce forum une solution à mon problème, mais je n'ai pas trouvé.
Quelqu'un aurait-il une solution pour me dépanner ?
J'ajoute le code de mon composant ici :
LabelNombreConversion.h
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
//---------------------------------------------------------------------------
#ifndef LabelNombreConversionH
#define LabelNombreConversionH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
//---------------------------------------------------------------------------
class PACKAGE TLabelNombreConversion : public TCustomLabel
{
private:
// ******************************** Ajouts *********************************
// *** Ajouts Tutoriel ***
TStringList *FListe;
int FIndice;
// *** Ajouts Perso ***
protected:
public:
__fastcall TLabelNombreConversion(TComponent* Owner);
// ******************************** Ajouts *********************************
// *** Ajouts Tutoriel ***
virtual __fastcall ~TLabelNombreConversion(); // Destructeur
void __fastcall ListeChange(TObject *Sender);
virtual void __fastcall SetListe(TStrings *AListe);
virtual TStrings* __fastcall GetListe();
virtual void __fastcall SetIndice(int AIndice);
AnsiString __fastcall GetLabelText();
// *** Ajouts Perso ***
double __fastcall valAbs(double nombreDepart); // Fonction valeur absolue
virtual void __fastcall afficheChaineConvertieUnite(AnsiString chaineNombreDepart);
__published:
// ******************************** Ajouts *********************************
// __property ;
// *** Ajouts Perso ***
__property Align;
__property Alignment;
__property Anchors;
__property AutoSize;
__property BiDiMode;
__property Caption;
__property Color;
__property Constraints;
__property Cursor;
__property DragCursor;
__property DragKind;
__property DragMode;
__property Enabled;
__property FocusControl;
__property Font;
__property Height;
__property HelpContext;
__property HelpKeyword;
__property HelpType;
__property Hint;
__property Layout;
__property Left;
__property Name;
__property ParentBiDiMode;
__property ParentColor;
__property ParentFont;
__property ParentShowHint;
__property PopupMenu;
__property ShowAccelChar;
__property ShowHint;
__property Tag;
__property Top;
__property Transparent;
__property Visible;
__property Width;
__property WordWrap;
// *** Ajouts Tutoriel ***
// Nouvelles propriétés
// Méthodes
// *** Ajouts Perso ***
__property OnClick;
__property OnContextPopup;
__property OnDblClick;
__property OnDragDrop;
__property OnDragOver;
__property OnEndDock;
__property OnEndDrag;
__property OnMouseDown;
__property OnMouseEnter;
__property OnMouseLeave;
__property OnMouseMove;
__property OnMouseUp;
__property OnStartDock;
__property OnStartDrag;
// *** Ajouts Tutoriel ***
// Nouvelles méthodes
__property int Indice = {read=FIndice, write=SetIndice};
__property TStrings *Liste = {read=GetListe, write=SetListe};
};
//---------------------------------------------------------------------------
#endif |
LabelNombreConversion.cpp
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "LabelNombreConversion.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
static inline void ValidCtrCheck(TLabelNombreConversion *)
{
new TLabelNombreConversion(NULL);
}
//---------------------------------------------------------------------------
__fastcall TLabelNombreConversion::TLabelNombreConversion(TComponent* Owner)
: TCustomLabel(Owner)
{
// ******************************** Ajouts *********************************
// Constructeur
Alignment=taRightJustify;
Caption = "+ 0 V";
Color=clBlack;
Font->Color=clWhite;
Font->Height=-19;
Font->Size=14;
Height=24;
Width=10;
// *** Ajouts Tutoriel ***
ControlStyle << csOpaque;
FListe = new TStringList();
FListe->OnChange = ListeChange;
FIndice = 0;
// Se gère avec la propriété
// Ajout de chaînes dans la liste
// FListe->Add("Lundi");
FListe->Add("0");
// *** Ajouts Perso ***
}
//---------------------------------------------------------------------------
// ******************************** Ajouts *********************************
// *** Ajouts Tutoriel ***
__fastcall TLabelNombreConversion::~TLabelNombreConversion()
{
delete FListe;
}
//---------------------------------------------------------------------------
// ******************************** Ajouts *********************************
// *** Ajouts Tutoriel ***
void __fastcall TLabelNombreConversion::SetIndice (int AIndice)
{
if (AIndice>=0 && AIndice < Liste->Count) FIndice = AIndice;
else Application->MessageBox("La valeur de l'indice hors limite.",
"Erreur", MB_OK);
Invalidate();
AdjustBounds();
}
//---------------------------------------------------------------------------
// ******************************** Ajouts *********************************
// *** Ajouts Tutoriel ***
AnsiString __fastcall TLabelNombreConversion::GetLabelText()
{
if(Liste->Count>0)
return Liste->Strings[Indice];
else return "Vide";
}
//---------------------------------------------------------------------------
// ******************************** Ajouts *********************************
// *** Ajouts Tutoriel ***
TStrings* __fastcall TLabelNombreConversion::GetListe()
{
return FListe;
}
//---------------------------------------------------------------------------
// ******************************** Ajouts *********************************
// *** Ajouts Tutoriel ***
void __fastcall TLabelNombreConversion::SetListe(TStrings *AListe)
{
FListe->Assign(AListe);
}
//---------------------------------------------------------------------------
// ******************************** Ajouts *********************************
// *** Ajouts Tutoriel ***
void __fastcall TLabelNombreConversion::ListeChange(TObject *Sender)
{
Invalidate();
AdjustBounds();
}
//---------------------------------------------------------------------------
// ******************************** Ajouts *********************************
// *** Ajouts Perso ***
double __fastcall TLabelNombreConversion::valAbs(double nombreDepart) // Fonction valeur absolue
{
double valeurAbsolue;
if (nombreDepart<0)
{
valeurAbsolue=(-1)*nombreDepart;
}
else
{
valeurAbsolue=nombreDepart;
}
return valeurAbsolue;
}
//---------------------------------------------------------------------------
// ******************************** Ajouts *********************************
// *** Ajouts Perso ***
void __fastcall TLabelNombreConversion::afficheChaineConvertieUnite(AnsiString chaineNombreDepart)
{
// Déclarations de variables
double nombreDepart;
nombreDepart=chaineNombreDepart.ToDouble();
double nombreConvertiUnite;
AnsiString chaineSigne;
AnsiString chainePrefixeUnite;
AnsiString unite="V";
AnsiString chaineNombreArrivee;
AnsiString chaineGlobaleArrivee;
bool valeurATraiter;
double facteurMultiplicateur;
// On vérifie qu'une chaine nombre a bien été rentrée.
if (chaineNombreDepart=="")
{
ShowMessage("Attention, vous devez rentrer une valeur !");
}
// Cas où la chaîne rentrée est numérique
if (chaineNombreDepart.ToDouble()!=0 || chaineNombreDepart=="0")
{
valeurATraiter=true;
// Cas d'un signe négatif
if (nombreDepart<0)
{
chaineSigne="-";
nombreDepart=valAbs(nombreDepart);
}
else
{
chaineSigne="+";
}
// Traitement de la valeur absolue
if (nombreDepart==0)
{
facteurMultiplicateur=1;
chainePrefixeUnite="";
}
else if(nombreDepart>=1)
{
if (nombreDepart > 1000000)
{
facteurMultiplicateur=0.000001;
chainePrefixeUnite="M";
}
else if (nombreDepart > 1000)
{
facteurMultiplicateur=0.001;
chainePrefixeUnite="k";
}
else
{
facteurMultiplicateur=1;
chainePrefixeUnite="";
}
}
else
{
if (nombreDepart < 0.000000000001)
{
facteurMultiplicateur=1;
chainePrefixeUnite="";
nombreDepart=0;
}
else if (nombreDepart < 0.000000001)
{
facteurMultiplicateur=1000000000000;
chainePrefixeUnite="p";
}
else if (nombreDepart < 0.000001)
{
facteurMultiplicateur=1E+09;
chainePrefixeUnite="n";
}
else if (nombreDepart < 0.001)
{
facteurMultiplicateur=1000000;
chainePrefixeUnite="µ";
}
else
{
facteurMultiplicateur=1000;
chainePrefixeUnite="m";
}
}
// Constitution de la chaîne à afficher
nombreConvertiUnite = nombreDepart * facteurMultiplicateur;
unite = chainePrefixeUnite.operator+(unite);
chaineNombreArrivee = AnsiString(nombreConvertiUnite);
chaineGlobaleArrivee = chaineSigne.operator +(" ");
chaineGlobaleArrivee = chaineGlobaleArrivee.operator +(chaineNombreArrivee);
chaineGlobaleArrivee = chaineGlobaleArrivee.operator +(" ");
chaineGlobaleArrivee = chaineGlobaleArrivee.operator +(unite);
// ********* Ancien affichage avec les TEdit **********
/* Affichage des valeurs dans les bonnes cases
Edit2->Clear();
Edit2->Text = chaineSigne;
Edit5->Clear();
Edit5->Text = AnsiString(nombreConvertiUnite);
Edit6->Clear();
Edit6->Text=unite;*/
// ********* Nouvel Affichage : tout dans un Label; *********
Caption = chaineGlobaleArrivee;
}
// Cas où la chaine rentrée n'est pas numérique
else
{
Caption="valeur non numérique";
}
}
//------------------------------------------------------------------------
namespace Labelnombreconversion
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TLabelNombreConversion)};
RegisterComponents("Compos_Itest_1", classes, 0);
}
}
//------------------------------------------------------------------------ |
Merci d'avance de vos réponses !