J'ai toujours mon erreur, la seule chose qui fonctionne correctement c'est l'icone, on ne peut pas etre mauvais partout.
Y a t'il possibilite de tester ce genre de code en pas a pas?
Version imprimable
J'ai toujours mon erreur, la seule chose qui fonctionne correctement c'est l'icone, on ne peut pas etre mauvais partout.
Y a t'il possibilite de tester ce genre de code en pas a pas?
En relisant ton code, je m'aperçois d'un détail qui m'avait échappé (d'autant plus que c'est moi qui t'avait dit de procéder ainsi :cry: ):
il ne faut pas faire:
mais:Code:char *capt = new char(Size+1);
J'espère que c'est la source de ton problème ...Code:char *capt = new char[Size+1];
Merci josse95 apparamment c'etait cela tout a l'air de fonctionner, moi tel le gros bourin avec ses grosses oeilleres je ne m'en suis pas apercu :oops:
maintenant ce que j'ai teste fonctionne voici le code complet.
Le .cpp
Le .hCode:
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 //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "StrUtils.hpp" // a ajouter #include "LabelVertical.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(TLabelVertical *) { new TLabelVertical(NULL); } //--------------------------------------------------------------------------- __fastcall TLabelVertical::TLabelVertical(TComponent* Owner) : TLabel(Owner) { } //--------------------------------------------------------------------------- void __fastcall TLabelVertical::SetVertical(bool AVertical) // SetVertical modifie la variable FVertical qui est la valeur // renvoyee par la propriete { if (AVertical != FVertical) { FVertical = AVertical; Invalidate(); AdjustBounds(); } } //--------------------------------------------------------------------------- AnsiString __fastcall TLabelVertical::GetLabelText() // on recupere le Caption du TLabel // redefinition de la fonction GetLabelText { if (FVertical) { // on lit la longueur du Caption Size = GetTextLen(); // on recupere le Caption char *capt = new char[Size+1]; GetTextBuf(capt,Size+1); // on reecrit la chaine du Caption tempd = ""; for (i=0;i<Size;i++) { tempd += capt[i]; tempd += '\n'; } // on ecrit le Caption //SetTextBuf(tempd); delete capt; return tempd; } else { // on lit la longueur du Caption Size = GetTextLen(); // on recupere le Caption char *capt = new char[Size+1]; GetTextBuf(capt,Size+1); // on reecrit la chaine du Caption tempd = ""; for (i=0;i<Size;i++) { switch (capt[i]) { case '\\' : { } break; case 'n' : { } break; default : tempd += capt[i]; } } delete capt; return tempd; } } //--------------------------------------------------------------------------- namespace Labelvertical { void __fastcall PACKAGE Register() { TComponentClass classes[1] = {__classid(TLabelVertical)}; RegisterComponents("Perso", classes, 0); } } //---------------------------------------------------------------------------
Je joind le zip de l'icone a decompacter dans le dossier du packageCode:
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 //--------------------------------------------------------------------------- #ifndef LabelVerticalH #define LabelVerticalH //--------------------------------------------------------------------------- #include <SysUtils.hpp> #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> //--------------------------------------------------------------------------- class PACKAGE TLabelVertical : public TLabel { private: // variable qui memorise la nouvelle propriete. bool FVertical; protected: // fonction qui modifie la nouvelle propriete. void __fastcall SetVertical(bool AVertical); AnsiString __fastcall GetLabelText(); // variable temporaire AnsiString tempd; int Size; int i; public: __fastcall TLabelVertical(TComponent* Owner); __published: // on reporte integralement les proprietes du TLabel // Properties __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; // nouvelle propriete __property bool Vertical = {read=FVertical, write=SetVertical, default=false}; // Events // __property FocusControl; __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; // __property PopupMenu; }; //--------------------------------------------------------------------------- #endif
Apparement toutes les fonctions du TLabel sont OK sauf la fonction "WordWrap" qui n'est operationel que sur le texte ecrit horizontalement, je ne sais pas comment on pourrait deriver cette fonction pour l'ecriture verticale, ce qui en ferait un composant complet.
Le wordwrap quand on écrit en vertical, je ne vois pas bien comment ça peut fonctionner. Tu veux dire que quand le texte atteind la hauteur du composant, celui-ci s'étend en largeur et le texte se poursuit sur une autre colonne ?
Oui mais je ne vois pas comment faire, c'est fonction de la taille des caracteres et de l'espace reserve pour l'ecriture
J'ai continue mes recherches il y aurait peut etre une solution pour utiliser WordWrap en ecriture verticale, le TLabel posede un Canvas il serait possible d'utiliser Canvas->Textout....., il me reste un probleme a resoudre comment definir la dimension du rectangle d'ecriture pour la chaine a afficher et en fonction de la taille des caracteres, et est il possible d'afficher deux fois Canvas->Textout..., pour le meme TLabel afin d'avoir deux ou plusieurs colonnes? :?
Il y a une solution plus simple:
tu calcules le nombre maximum de caractères que tu peux afficher en hauteur (à l'aide de Height et de Canvas->TextHeight).
Et tu construis le Caption en conséquence.
Ex: si tu trouves 5 caractères au maximum et que ton Caption d'origine est abcdefghi, tu construis:
Caption="a f\nb g\nc h\nd i\ne\n";
[EDIT]: finalement, à bien y réfléchir, cette méthode ne fonctionne qu'avec des polices à espacement fixe (sinon, les colonnes ne seront pas alignées).
Bref, ce n'est pas la solution.
Merci josse95:
Ce qui me gene le plus pour l'instant c'est le traitement de la chaine de caracteres pour l'ordonner soit dans un tableau ou autre..
Le probleme d'un tableau c'est que je ne connais pas sa dimension avant traitement et je ne sais pas si on peut le redimensionner en cours de traitement, si j'utilise un TStringlist je ne vois pas comment recuperer un caractere sur chaque String pour ecrire une ligne, je ne sais pas si je peu utiliser un TStringGrid invisible (on peut ajouter des lignes et des colonnes) mettre un caractere par cellule en ecrivant par colonne et recreer une chaine en relisant par ligne.
Quand a la police de caracteres dans trucs et astuces il y a quelque chose sur les polices qui ne fonctionnent pas en ecriture verticale.
Je viens de reussir a simuler le WorWrap Vertical a l'aide d'un StringGrid j'ai bien galere, mais la le code a l'air de fonctionner correctement a chaque modification.
Le code:
Il me reste trois problemesCode:
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 void __fastcall TForm1::ColorBtn3Click(TObject *Sender) { String text1 = "essai d'ecriture de texte sur plusieurs colonnes"; text1 = text1 + " "; int lngtxt = text1.Length(); int lngtxt1; int htlabel = Label1->Height; int htcar = Label1->Font->Height; int nbcar = htlabel / -htcar; int k = 0; int rst = nbcar; int bcl = 0; StringGrid1->FixedCols = 0; StringGrid1->FixedRows = 0; StringGrid1->RowCount = nbcar; AnsiString c = ""; AnsiString d =""; for (int i = 0; i <= lngtxt; i++) { c = MidStr(text1, i + 1, 1); d = d + c; if (c == " ") { lngtxt1 = d.Length(); if (bcl != 0 && rst < lngtxt1) { k = k + 1; rst = nbcar; bcl = 0; } if (bcl == 0 && rst > lngtxt1) { rst = nbcar; bcl = 0; } for (int j = 0; j <= lngtxt1; j++) { c = MidStr(d, j + 1, 1); // Cells[colonne][ligne] StringGrid1->Cells[k][j + bcl] = c; } bcl = bcl + lngtxt1; rst = rst - lngtxt1; d = ""; } } d = ""; for (int j = 0; j <= nbcar; j++) { for (int i = 0; i <= k; i++) { c = StringGrid1->Cells[i][j]; if (c == "") { c = " "; } d = d + c; }// fin for i d = d + "\n"; }// fin for j Edit1->Text = d; }
1 - comment recuperer la Hauteur du TLabel qui n'est pas encore defini
2 - comment recuperer la Hauteur du caractere de la Fonte
3 - faire une bascule entre le WorWrap et le WordWrap Vertical quand l'un est a true l'autre est a false vise et versa
Je sais comment faire l'affichage du texte quelque soit la police en utilisant une fonction d'ecriture de ce style.
Par contre je n'ai toujours pas trouve comment recuperer les caracteristiques du TLabel alors qu'il n'est pas cree, car il me faut acquerir la position du Canvas, Top, Left,Height, Width, ainsi que la dimension de la Fonte si l'on pouvait mindiquer ou chercher:?Code:
1
2
3
4
5 TRect TheRect; // Gauche, Haut, Droite, Bas TheRect = Rect(20,20,30,35); Canvas->TextRect(TheRect, 20, 20, "H");
Je viens de trouver une solution pour le WordWrapVertical.
Le code:
Il me reste a integrer ce code dans celui du TLabelVertical que j'ai creeCode:
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 void __fastcall TForm1::ColorBtn3Click(TObject *Sender) { int zz = Label1->Canvas->TextHeight(Caption); int yy = Label1->Canvas->TextWidth(Caption); int Gauche = 0; int Haut = 0; int Droite = yy; int Bas = zz; TRect TheRect; String text1 = "essai d'ecriture de texte sur plusieurs colonnes"; text1 = text1 + " "; int lngtxt = text1.Length(); int lngtxt1; int htlabel = Label1->Height; int nbcar = htlabel / zz; int k = 0; int rst = nbcar; int bcl = 0; AnsiString c = ""; AnsiString d =""; for (int i = 0; i <= lngtxt; i++) { c = MidStr(text1, i + 1, 1); d = d + c; if (c == " ") { lngtxt1 = d.Length(); if (bcl != 0 && rst < lngtxt1) { k = k + 1; rst = nbcar; bcl = 0; } if (bcl == 0 && rst > lngtxt1) { rst = nbcar; bcl = 0; } for (int j = 0; j <= lngtxt1; j++) { c = MidStr(d, j + 1, 1); // ici on fait l'affichage // Gauche, Haut, Droite, Bas TheRect = Rect(Gauche + (k * 15), Haut + ((j + bcl) * (zz - 2)), Droite + (k * 15), Bas + ((j + bcl) * (zz - 2))); Label1->Canvas->TextRect(TheRect, Gauche + (k * 15), Haut + ((j + bcl) * (zz - 2)), c); } bcl = bcl + lngtxt1; rst = rst - lngtxt1; d = ""; } } d = ""; }
Il me reste un probleme a resoudre je vais ajouter une fonction WordWrapVertical avec deux possibilitees (TRUE, FALSE) mais est ce que je peu intervenir sur WordWrap horizontal a partir du WordWrapVertical je m'explique je peu avoir
WorWrapVertical = false et WordWrap horizontal = false
WorWrapVertical = false et WordWrap horizontal = true
WorWrapVertical = true et WordWrap horizontal = false
mais absolument pas
WorWrapVertical = true et WordWrap horizontal = true
Comment intervenir sur le WordWrap horizontal sans devoir reecrir la fonction d'origine
Salut blondelle,
Un TLabel avec une propriété d'écriture verticale, à bien y réfléchir la propriété WordWrap le fait.
Mais peut-être pas comme tu le souhaites ?
Je m'explique, la propriété fait un passage à la ligne à chaque foi qu'elle rencontre un espace et que le TLabel n'est pas assez large.
Alors si tu t'arranges pour qu'une propriété "WordWrapBis" face le passage à la ligne systématiquement après chaque caractère, et bien là tu as ton écriture verticale et que peut être même tes récents problèmes serait résolut.
Bon, ce n'est qu'une suggestion, à cogiter donc. ;)
Merci pour ta reponse maxim_um:
J'y avais pense mais ca ne fonctionne pas avec plusieurs colonnes :aie:
Le code est fonctionnel mais a adapter mon soucis est de recuperer la hauteur et la largeur du texte, la hauteur et la largeur du Canvas, il me faut aussi intervenir sur la selection du WorWrap horizontal et le WordWrapVertical car ils ne peuvent pas etre a true tous les deux
Voilà quelques bouts de code, ils parlent d'eux-mêmes.
Code:
1
2 void _fastcall SetWorWrapVertical (bool value);
Code:
1
2 __proprety bool WorWrapVertical = {read=GetWorWrapVertical, write=SetWorWrapVertical, default=false };
La mesure de la hauteur de la Font:Code:
1
2
3
4
5
6 void _fastcall SetWorWrapVertical (bool value) { if (value == true && Label1->Wordwrap==true) { Label1->WordWrap = false } else {Label1->WorWrapVertical=value}; }
Je ne sais pas si ça répond à tes attentes, mais si cela peut t'aider, j'en serais satisfait...Code:
1
2int HauteurFont = Label1->Font->Size;
Merci pour ta reponse maxim_um:
J'ai trouve aussi ceci:
Je ne peu pas utiliser Label1 car il n'est pas cree, ce n'est pas evident de trouver les fonctions de base du composant car on ne peut pas faire reference a ce composant on est en train de le creerCitation:
int zz = GetClientHeight
int yy = GetClientWidth
Je comprends mieux ta galère ... :arf:
Dommage que ceux qui maîtrisent ce genre de chose ne te viennent pas en aide,
ton problème serait vite réglé.
Ma fois en ce qui me concerne, je te souhaite un bon courage... :ccool:
Merci maxim_um:
C'est un composant pour un usage perso donc il n'y a pas urgence, et comme cela je fais des decouvertes en faisant les recherches :P
Salut !
Je suis parti de l'idée suivante (ce n'est qu'une base de réflexion parce que je ne prend pas encore tout en compte) :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 class jLabel : public TCustomLabel { private : bool FVertical; int he; int we; protected : void __fastcall SetVertical(bool Value); public : __fastcall jLabel(TComponent *Owner); __fastcall ~jLabel(); void __fastcall Paint(); void __fastcall VDraw(AnsiString N, int X); __property bool Vertical={read=FVertical, write=SetVertical, default = false}; };
J'ai testé comme suit :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 __fastcall jLabel::jLabel(TComponent *Owner) : TCustomLabel(Owner) { if(Owner->InheritsFrom(__classid(TWinControl))) Parent = (TWinControl*)Owner; Caption = "ESSAI LABEL1 by henderson"; FVertical = true; WordWrap = true; } __fastcall jLabel::~jLabel() { } void __fastcall jLabel::Paint() { if(FVertical == false) { //Donc horizontal TCustomLabel::Paint(); } else { //Donc vertical Canvas->Font->Assign(Font); we = Canvas->TextWidth("W"); he = Canvas->TextHeight("W"); Canvas->Brush->Color = Parent->Brush->Color; if(WordWrap == false) { VDraw(Caption, 2); } else { if((Caption.Length() * we) < Height) { VDraw(Caption, 2); } else { AnsiString N = Caption; int pos; int x = 2; while(N != "") { pos = N.Pos(" "); if(pos != 0) { VDraw(N.SubString(1, pos-1), x); N = N.SubString(pos+1, N.Length()); x = x + we; } else { VDraw(N, x); N = ""; } } } } } } void __fastcall jLabel::VDraw(AnsiString N, int X) { int y = 2; for(int j = 1; j <= N.Length(); j++) { Canvas->TextOut(X, y, N[j]); y+=he; } } void __fastcall jLabel::SetVertical(bool Value) { if(FVertical != Value) { FVertical = Value; Repaint(); } }
Code:jLabel *Label;
Si j'ai le temps, j'irai un peu plus loin, en particulier pour l'Autosize et Alignement qui demandent un peu de réflexion !Code:
1
2
3
4
5
6 __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Label = new jLabel(this); Label->SetBounds(50,50,50,120); }
A plus !
Salut henderson:
Merci pour ta reponse, je suis parti sur une idee un peu differente j'ecrit caractere par caractere dans des Trect et je fais un teste mot par mot pour le WordWrap c'est plus facile a gerer a mon sens que la chaine complete dans un Trect meme si le code est un peu plus long, la lecture de ton code ma fais voir que je n'avais pas pense a l'Autosize.
J'ai trouve sur le site un Tuto Delphi7 intitule " Guide du concepteur de composants "
Le lien
Ce qui me gene surtout ce n'est pas l'ecriture des fonctions mais la recuperation des infos comme la largeur et le hauteur du Canvas, la largeur et la hauteur des caracteres, je n'ai pas encore assimile la facon de faire, j'espere que cela viendra :P
Encore une fois merci pour ton code.