Salut,
Pour imprimer un canvas, regarde du coté de la classe TPrinter
Salut,
Pour imprimer un canvas, regarde du coté de la classe TPrinter
Quand une réponse vous a été utile, pensez à utiliser le nouveau système de notation
Lisez le magazine de developpez.com. Mes tutos : http://pottiez.developpez.com
La FAQ BCB -> 642 Questions/Réponses, si vous voulez participer, contactez moi. Aide de BCB6 en français
N'oubliez pas que l'aide existe et est affichée sous simple pression de la touche F1 , une touche c'est plus rapide que tout un message .
Salut !
Pourquoi ne pas développer une classe à partir de ce que nous offre BCB, en dérivant :
- soit de TComponent si on n'a pas besoin d'écho (doté malgré tout d'un Graphics::TBitmap... pourquoi pas ?)
- soit de TCustomConntrol (en fait à partir de TGraphicControl... TPaintBox... TCustomForm...TForm... en un mot tout ce qui possède un TCanvas) pour faire écho du code barres avant impression.
Voici un début de développement (et comme j'aime bien dériver de TCustomControl...):
Pour les méthodes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #include <Printers.hpp> class jCodeBarres : public TCustomControl { private : //Le texte à coder AnsiString FCaption; //j'utilise le type TScrollBarKind pour faire court TScrollBarKind FKind; //... protected : void __fastcall SetCaption(AnsiString Value); void __fastcall SetKind(TScrollBarKind Value); //... public : __fastcall jCodeBarres(TComponent* AOwner); __fastcall ~jCodeBarres(); //... //... void __fastcall Paint(); void __fastcall Print(); __property AnsiString Caption={read=FCaption, write=SetCaption}; __property TScrollBarKind Kind={read=FKind, write=SetKind}; //... };
Si on devait dériver qu'un TComponent avec un Bitmap, la méthode Print pourrait utiliser :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 __fastcall jCodeBarres::jCodeBarres(TComponent* AOwner) : TCustomControl(AOwner) { if(AOwner->InheritsFrom(__classid(TWinControl))) Parent = (TWinControl*)AOwner; } __fastcall jCodeBarres::~jCodeBarres() { } void __fastcall jCodeBarres::Paint() { if(Kind == sbHorizontal) { //Barres horizontales //... } else { //Barres verticales //Je vais aller dans l'originalité... //on sait qu'il suffit de ne dessiner qu'une ligne //on sera donc amené à ne faire que des : //Canvas->Pixels[x][0]=clBlack; x++; //de barre en barre (ou traits) et pour les blancs : //Canvas->Pixels[x][0]=clWhite; x++; //vient ensuite le remplissage //on duplique la première ligne sur les autres lignes TColor Color; for(int x = 0; x < width; x++) { Color = Canvas->Pixels[x][0]; for(int y = 1; y < height; y++) { Canvas->Pixels[x][y] = Color; } } } } void __fastcall jCodeBarres::Print() { //brut... mais c'est à calculer... //probablement à reécrire dans une boucle (ici ???) int x=0; int y=0; //les rects pour la recopie d'un canvas vers un autre TRect Srce = Rect(0, 0, Width, Height); TRect Dest = Rect(x, y, x + Width, y + Height); //Le travail d'impression commnce ici : Printer()->BeginDoc(); //... gérer une ou deux boucles pour remplir une feuille ? Printer()->Canvas->CopyRect(Dest, Canvas, Srce); //... donc pour les boucles c'est à voir... //... et fin d'impression Printer()->EndDoc(); } void __fastcall jCodeBarres::SetCaption(AnsiString Value) { FCaption = Value; Repaint(); } void __fastcall jCodeBarres::SetKind(TScrollBarKind Value) { if(FKind != Value) { FKind = Value; Repaint(); } }
La classe donnée en exemple n'est qu'un début de développement !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 //... Printer()->Canvas->Draw(x,y, Bitmap); //...
C'est juste une idée... et ça peut rendre service à d'autres !
A plus !
Je n'arrive pas du tout à imprimer mes code-barres. Mon code-barre se trouve un objet QrEan. Est-ce que quelqu'un peut m'aider ?
Salut !
Voici ce que j'ai finalement développé (juste pour le fun).
Pour la représentation graphique, j'ai écarté la proportionnalité.
En effet, c'est un premier jet et ... il n'existe pas de 1/2 pixels...
J'ai cherché avant tout à obtenir un écho sur l'écran.
Le CodeBarre.h :
Le CodeBarre.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #include <Printers.hpp> // les types co40 et co41 sont ici factices et ne sont la que pour illustrer enum TCodeType{co39, co40, co41}; class jCodeBarres : public TCustomControl { private : bool Done; AnsiString FCaption; TScrollBarKind FKind; TCodeType FType; AnsiString wn; AnsiString bcarray; AnsiString textcopy; //Je prends des int car il n'existe pas de 1/2 pixels int d_offset; int d_taillebarcode; int d_barwidth; protected : void __fastcall SetCaption(AnsiString Value); void __fastcall SetKind(TScrollBarKind Value); void __fastcall SetType(TCodeType Value); public : __fastcall jCodeBarres(TComponent* AOwner); __fastcall ~jCodeBarres(); //... void __fastcall DrawChar(int J, int X, int Y); void __fastcall Encode39(char C); //Encodages factices void __fastcall Encode40(char C); void __fastcall Encode41(char C); void __fastcall Encode(char C); void __fastcall Paint(); void __fastcall Print(); //Le texte à encoder __property AnsiString Caption={read=FCaption, write=SetCaption}; //Traits verticaux ou horizontaux __property TScrollBarKind Kind={read=FKind, write=SetKind}; //Type d'encodage en relation avec l'énumération TCodeType __property TCodeType Type={read=FType, write=SetType}; //Pour accéder au canvas __property TCanvas *Cnv={read=Canvas}; };
J'ai donc utilisé de cette manière là (dans Unit1.cpp):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 __fastcall jCodeBarres::jCodeBarres(TComponent* AOwner) : TCustomControl(AOwner) { if(AOwner->InheritsFrom(__classid(TWinControl))) Parent = (TWinControl*)AOwner; Canvas->Brush->Style = bsSolid; Canvas->Pen->Style = psSolid; Canvas->Pen->Mode = pmCopy; FKind = sbVertical; Canvas->Pen->Color = clBlack; Canvas->Font->Size = 12; Canvas->Font->Style = Canvas->Font->Style << fsBold; Done = false; } __fastcall jCodeBarres::~jCodeBarres() { } void __fastcall jCodeBarres::Encode39(char C) { int N = 0; switch(C) { case '*': N = 0x0094; break; case '1': N = 0x0121; break; case '2': N = 0x0061; break; case '3': N = 0x0160; break; case '4': N = 0x0031; break; case '5': N = 0x0130; break; case '6': N = 0x0070; break; case '7': N = 0x0025; break; case '8': N = 0x0124; break; case '9': N = 0x0064; break; case '0': N = 0x0034; break; case 'A': N = 0x0109; break; case 'B': N = 0x0049; break; case 'C': N = 0x0148; break; case 'D': N = 0x0019; break; case 'E': N = 0x0118; break; case 'F': N = 0x0058; break; case 'G': N = 0x000D; break; case 'H': N = 0x010C; break; case 'I': N = 0x004C; break; case 'J': N = 0x001C; break; case 'K': N = 0x0103; break; case 'L': N = 0x0043; break; case 'M': N = 0x0142; break; case 'N': N = 0x0013; break; case 'O': N = 0x0112; break; case 'P': N = 0x0052; break; case 'Q': N = 0x0007; break; case 'R': N = 0x0106; break; case 'S': N = 0x0046; break; case 'T': N = 0x0016; break; case 'U': N = 0x0181; break; case 'V': N = 0x00C1; break; case 'W': N = 0x01C0; break; case 'X': N = 0x0091; break; case 'Y': N = 0x0190; break; case 'Z': N = 0x00D0; break; case '-': N = 0x0085; break; case '.': N = 0x0184; break; case ' ': N = 0x00C4; break; case '$': N = 0x00A8; break; case '/': N = 0x00A2; break; case '+': N = 0x008A; break; case '%': N = 0x002A; break; } if(N != 0) { wn = "0000000000"; wn[9] = (char)(wn[9] + (N & 1)); N = N >> 1; wn[8] = (char)(wn[8] + (N & 1)); N = N >> 1; wn[7] = (char)(wn[7] + (N & 1)); N = N >> 1; wn[6] = (char)(wn[6] + (N & 1)); N = N >> 1; wn[5] = (char)(wn[5] + (N & 1)); N = N >> 1; wn[4] = (char)(wn[4] + (N & 1)); N = N >> 1; wn[3] = (char)(wn[3] + (N & 1)); N = N >> 1; wn[2] = (char)(wn[2] + (N & 1)); N = N >> 1; wn[1] = (char)(wn[1] + (N & 1)); bcarray = bcarray + wn; } } void __fastcall jCodeBarres::Encode40(char C) { } void __fastcall jCodeBarres::Encode41(char C) { } void __fastcall jCodeBarres::Encode(char C) { switch(Type) { case co39 : Encode39(C); break; case co40 : Encode40(C); break; // factice case co41 : Encode41(C); break; // factice } } void __fastcall jCodeBarres::DrawChar(int J, int X, int Y) { int c = (J-1) % 10; if(c == 0) { int p = (J-1) / 10; Canvas->Brush->Color = clWhite; Canvas->TextOut(X, Y, (AnsiString) textcopy[p+1]); Canvas->Brush->Color = clBlack; } } void __fastcall jCodeBarres::Paint() { //si texte > 30 caractéres on imprime pas le code à barre if(Caption.Length() <= 30) { //Si Done == true, c'est que SetBounds a été sollicitée //Il n'est donc pas necéssaire de tout recalculer //Par contre si Done == false, alors il faut tout calculer if(Done == false) { Done = true; //Tout Effacer Canvas->Brush->Color = clWhite; Canvas->Brush->Color = clWhite; Canvas->FillRect(Rect(0,0,Width, Height)); //Pour dessiner Canvas->Brush->Color = clBlack; Canvas->Brush->Color = clBlack; //On purge la chaîne des binaires bcarray = ""; // Apparemment on encadre l'expression à codifier par deux "*" donc : textcopy = "*" + Caption.UpperCase() + "*"; //On encode textcopy dans le bcarray for(int j = 1; j <= textcopy.Length(); j++) { Encode(textcopy[j]); } //raz des propriétés d_offset = 0; d_taillebarcode = 0; //On calcule une dimension totale du code barre //- barre de 6 pour 1 //- barre de 2 pour 0 for(int j=1; j<= bcarray.Length(); j++) { if(bcarray[j] == '1') d_taillebarcode += 6; else d_taillebarcode += 2; } } // au cas ou Done == true // les dimensions sont celles données à SetBounds // donc on n'y fera pas appel cette fois ci // REM : sbVertical pour des barres verticales if(Kind == sbVertical) { //J'affecte la bonne taille à l'objet if(Width != d_taillebarcode) { SetBounds(Left,Top, d_taillebarcode, 64); return; // A ce stade le code barre est dessiné } for(int j = 1; j<= bcarray.Length(); j++) { DrawChar(j, d_offset, Height - 16); //par défaut 2 pour un 0, sinon 6 pour un 1 d_barwidth = 2; if(bcarray[j] == '1') d_barwidth = 6; if((j & 1) == 1) { Canvas->Rectangle(d_offset, 0, d_offset + d_barwidth, Height - 16); } d_offset += d_barwidth; } } else { if(Height != d_taillebarcode) { SetBounds(Left,Top, 64, d_taillebarcode); return; } for(int j = 1; j<= bcarray.Length(); j++) { DrawChar(j, Width-16, d_offset); d_barwidth = 2; if(bcarray[j]=='1') d_barwidth = 6; if((j & 1) == 1) { Canvas->Rectangle(0, d_offset, Width - 16, d_offset + d_barwidth); } d_offset += d_barwidth; } } } //Prêt pour dessiner à nouveau Done = false; } void __fastcall jCodeBarres::Print() { //Positions du code barre sur la feuille à imprimer //Donc à modifier... int x = 0; int y = 0; //les rects pour la recopie d'un canvas vers un autre TRect Srce = Rect(0, 0, Width, Height); TRect Dest = Rect(x, y, x + Width, y + Height); Printer()->BeginDoc(); Printer()->Canvas->CopyRect(Dest, Canvas, Srce); Printer()->EndDoc(); } void __fastcall jCodeBarres::SetCaption(AnsiString Value) { FCaption = Value; Repaint(); } void __fastcall jCodeBarres::SetKind(TScrollBarKind Value) { if(FKind != Value) { FKind = Value; Repaint(); } } void __fastcall jCodeBarres::SetType(TCodeType Value) { if(FType != Value) { FType = Value; Repaint(); } }
Comme je n'ai pas d'imprimante je n'ai pas vérifié l'impression.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include "CodeBarre.h" jCodeBarres *CodeBarre; //------------------------------------------------------------------------ __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { CodeBarre = new jCodeBarres(this); CodeBarre->SetBounds(20,20,100,64); CodeBarre->Caption = "3020061"; } //------------------------------------------------------------------------
Donc j'espère que je ne serai pas le seul à travailler sur cette classe !
A plus !
Salut je voulais juste vous dire que j'ai trouvé un composant gratuit pour BCB (tbarcode) il fait le EAN-13: http://tvilda.stilius.net/tbarcode/
- Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
- Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
- Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon
J'ai encore trouvé quelque chose que je veux partager avec vous, il y a un site Web qui offre d'utiliser des polices de caractères pour généré un code barres: http://grandzebu.net/index.php?page=...bar/codbar.htm
Il a y a des exemples de code en VB et même une DLL en C++ (compatible BCB ???).
- Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
- Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
- Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon
Désolé pour le retard.
Hendersen : merci d'avoir codé cette classe mais comme je l'avais dit plus haut j'ai trouvé un Composant qui me permet de créer mes code-barres. Le problème en était l'impression. J'ai un peu galéré mais je suis qd même arrivé à quelque chose de correct. Voici ce que j'ai fait :
J'ai réalisé un capture d'écran de mon TabSheet, ensuite de cette capture j'en ai extrait un rectangle dans lequel se trouve le code-barre. Ce rectangle est ensuite mis dans un TImage que je fait ensuite imprimer.
Voici le code :
Crayon : Ton compsant a l'air pas mal mais ton lien est mort. J'ai essayer de trouver un autre lien mais ca me ramène à chaque fois sur le même site. Au pire j'ai déjà le mien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 if(Start_Print->Execute()) { Image3->Height = BarCode1->Height; Image3->Width = BarCode1->Width; Image3->Picture->Bitmap->Height = BarCode1->Height; Image3->Picture->Bitmap->Width = BarCode1->Width; HDC PanelSRC = GetWindowDC(BarCode1->Handle); BitBlt(Image3->Picture->Bitmap->Canvas->Handle, 0, 0, BarCode1->Width, BarCode1->Height, PanelSRC, 0, 0, SRCCOPY); ReleaseDC(GetDesktopWindow(), PanelSRC); TPrinter *Prntr = Printer(); TRect r = Rect(1350,900,Image3->Picture->Bitmap->Height,Image3->Picture->Bitmap->Width); Prntr->BeginDoc(); Prntr->Canvas->StretchDraw(r,Image3->Picture->Bitmap); Prntr->Canvas->FrameRect(r); Prntr->EndDoc(); }
Le problème est que si j'imprime un code-barre assez petit, la douchette n'arrive pas à le lire. Peut-être que ton composant a une meilleure précision
Je viens de remarquer que j'ai un petit souci au niveau de l'impression. Quand j'imprime sur mon imprimante, rien ne s'imprime. Par contre quand j'imprime sur mon imprimante PDF (PDFCreator) le code-barre est bien affiché. A partir du pdf l'impression du code-barre fonctionne correctement.
Je ne comprend pas pourquoi cela ne fontionne pas sur mon imprimante. Avez-vous une idée ?
Salut !
Ton rectangle se calcule normalement ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 TRect r = Rect(1350, //left 900, //top 1350 + Image3->Picture->Bitmap->Width, // right 900 + Image3->Picture->Bitmap->Height); // bottom
J'ai rajouté EAN8 et EAN13 dans ma classe... mais comme elle n'intéresse pas ici alors je vais garder tout ça en réserve !
A plus !
Ce n'est pas que je veux pas utiliser ta classe (merci d'avoir penché sur mon problème) mais j'ai un composant qui fait tout tout seul.
Cela dit, mon problème n'est toujours pas résolu. L'impression me donne une page blanche alors qu'avec l'impression de pdfcreator, le code-barre est bien affiché.
A partir du fichier pdf, si j'imprime le code-barre ca fonctionne normalement. Mais c'est vraiment pas terrible comme solution.
Si quelqu'un avait une autre solution pour imprimer mon code-barre ?
Il n'y a pas une histoire de dysfonctionnement entre certaines imprimantes et StretchDraw ?
Avec ta classe, l'impression se fait-elle correctement ?
Salut !
C'est pour cette raison que je n'était pas très chaud pour dessiner mes propres code barres avec un stretch à cause des fractions de pixels.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 // A fixer expérimentalement ou à l'aide de //int ppi = Printer()->Canvas->Font->PixelsPerInch; //??? double stretch_factor = ....; //Le stretch sur un bitmap temporaire Graphics::TBitmap *Temp = new Graphics::TBitmap; Graphics::TBitmap *D = Image3->Picture->Bitmap; Temp->Width = D->Width * stretch_factor; Temp->Height = D->Height * stretch_factor; Temp->Canvas->StretchDraw(Rect(0,0,Temp->Width, Temp->Height), D->Canvas); // l'impression Printer()->BeginDoc(); Printer()->Canvas->Draw(X,Y, Temp); //.. Printer()->EndDoc(); delete Temp;
Il vaut mieux dessiner à l'échelle 1 (ou 2) et ne faire qu'un seul stretch.
Il faudrait vérifier les coordonnées (X,Y) de l'impression...
Je n'ai pas d'imprimante sous la main donc...
A plus !
J'ai voulu essayer ta classe mais il me met une erreur à la compilation :
Tu n'a pas d'idée sur mon problème d'impression ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part [C++ Erreur] Main.cpp(511): E2034 Impossible de convertir 'jCodeBarres *' en 'TLabel *'
Salut !
Et la solution avec le bitmap temporaire (pour effectuer un stretch) ?
Normalement, si ton imprimante sait imprimer des images ça devrait le faire !
Pour le problème avec jCodeBarre (qui dérive de TCustomControl) c'est le nom de la classe donc... je ne vois pas ce que TLabel vient faire ici ?
A plus !
Je viens d'essayer mon programme chez moi, et l'impression s'est effectuée correctement sur mon imprimante (en ne prenant pas compte de tes modification). L'imprimante au boulot est une imprimante laser.
J'essayerai demain matin au boulot ta solution avec le Bitmap temporaire. Dans cette solution, a quoi correspond stretch_factor ? Je dois lui affectuer quoi comme valeur ?
Pour en revenir à ta classe, en fait je dois avoir un label qui s'apelle CodeBarre car je viens de l'essayer sur mon portable dans un nouveau projet et ça a marché.
Il y a autre chose que j'aimerai bien réaliser mais je sais pas si c'est possible, c'est de pouvoir imprimer 10 code-barres (par exemple de 0000001 à 0000010) sur une même page ?
Salut !
Pour le stretch_factor, c'est le ratio appliqué sur Width et Height pour leur donner les dimensions voulues.
Une valeur de 0.5 revient à diviser par 2 et donc...
On peut bien sur travailler avec deux stretch_factor : l'un pour la largeur et l'autre pour la hauteur (C'est le cas pour TImage vis à vis de son bitmap).
Ici, avec un seul stretch_factor, ça revient à faire un zoom sur l'image (agrandissement ou rétrécissement).
Imprimer 10 barcodes ?
- 10 fois le même ?
- 10 barcodes différents ?
A plus !
Ok, j'essayerai ça demain matin au boulot. Donc mon problème d'impression viendrai de l'imprimante laser.
Il faudrait imprimer 10 code-barres différents (de 0000001 à 0000010) par exemple). C'est possible ?
Avec la solution avec le bitmap temporaire, ca me dit :
A quoi correspondent les variables X et Y ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part [C++ Erreur] Main.cpp(508): E2034 Impossible de convertir 'TCanvas *' en 'TGraphic *'
Henderson, dans ta classe comment je peux faire pour augmenter la hauteur du code-barre sans modifier sa largeur ?
Le site mentionné plus haut fonctionne maintenant. Sinon, le code peut se trouver sur http://sourceforge.net/projects/tbarcode/
Je reviens sur ce point juste au cas ou vous avez besoin d'un exemple de composant.
- Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
- Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
- Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager