IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

[SRC] Cherche piste pour TLabel orientable


Sujet :

C++Builder

  1. #1
    Membre averti

    Inscrit en
    Novembre 2004
    Messages
    17
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 17
    Par d�faut [SRC] Cherche piste pour TLabel orientable
    Bonjour,

    je dois �crire un composant, h�ritant de TLabel, orientable � 360�. Le seul exemple trouv� sur le net est justement disponible sur la partie Delphi de ce site, language que je ne ma�trise absolument pas


    Ma question est simple : j'ai besoin d'une piste o� commencer � chercher. Existe-t'il des fonctionnalit�s du canvas qui seraient utilisables ? dans l'objet TFont ?

    Merci pour toute r�ponse.


    En lien le composants en version Delphi (bravo � l'auteur) : http://nono40.developpez.com/sources/source0011/

    Edition par la r�daction : retrouvez cette r�alisation sur la page sources http://c.developpez.com/sources/bcb/?page=composants#labelorientable

  2. #2
    Membre �prouv�
    Homme Profil pro
    VP of Research and Innovation
    Inscrit en
    Mai 2002
    Messages
    84
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 54
    Localisation : Canada

    Informations professionnelles :
    Activit� : VP of Research and Innovation

    Informations forums :
    Inscription : Mai 2002
    Messages : 84
    Par d�faut
    Bonjour,

    Il faut d�river le composant Parent de TLabel (je te laisse chercher ).
    Ensuite tu dois �crire la fonction Paint de ce composant.

    A noter que seul les polices True Type peuevnt �tre directement inclin�e, sinon il faut faire tourner l'image r�sultante.

    Regarde la stuctute de la font native Windows (LOGFONT), param�tre escapement (lfEscapement) et rotation (lfRotation).

    J'ai un exemple.

  3. #3
    Membre averti

    Inscrit en
    Novembre 2004
    Messages
    17
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 17
    Par d�faut
    L'h�ritage du TLabel n'est pas un probl�me en soit, je ne suis (heureusement) pas � mon 1er composant

    Par contre merci beaucoups pour les indications au niveau de la Font. Je chercherais de ce cot�.

  4. #4
    Membre �prouv�
    Homme Profil pro
    VP of Research and Innovation
    Inscrit en
    Mai 2002
    Messages
    84
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 54
    Localisation : Canada

    Informations professionnelles :
    Activit� : VP of Research and Innovation

    Informations forums :
    Inscription : Mai 2002
    Messages : 84
    Par d�faut
    De rien.

    A noter que tu dois cr�er une Font compatible Windows et affecter le Handle � un objet TFont.
    C'est un peut space mais �a fonctionne.

  5. #5
    Membre �clair� Avatar de Rodrigue
    Inscrit en
    Ao�t 2002
    Messages
    487
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2002
    Messages : 487
    Par d�faut
    Il me semble qu'il y a �a dans le projet "Jedi"

  6. #6
    Membre �prouv�
    Homme Profil pro
    VP of Research and Innovation
    Inscrit en
    Mai 2002
    Messages
    84
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 54
    Localisation : Canada

    Informations professionnelles :
    Activit� : VP of Research and Innovation

    Informations forums :
    Inscription : Mai 2002
    Messages : 84
    Par d�faut
    Le projet Jedi est �crit en Pascal, Langage que notre Padawan ne maitrise pas

    Le seul exemple trouv� sur le net est justement disponible sur la partie Delphi de ce site, language que je ne ma�trise absolument pas

  7. #7
    Membre �clair� Avatar de Rodrigue
    Inscrit en
    Ao�t 2002
    Messages
    487
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2002
    Messages : 487
    Par d�faut
    OK, d�sol�

  8. #8
    Membre averti

    Inscrit en
    Novembre 2004
    Messages
    17
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 17
    Par d�faut
    Rebonjour,

    merci encore pour votre aide � tous. Ci-dessous mon composants � l'�tat actuel. La rotation du texte au centre du label fonctionne, mais il me reste quelques petits points � corriger.

    1/ Lorsque l'angle est de 90, 180, 270 ou 360�, la LOGFONT prend un angle de 0�. Alors qu'un angle de 91� par exemple marche tr�s bien. Pourquoi ?

    2/ J'ai essay� de nombreuses choses, mais j'ai quelques difficult�s avec les polices. Ma LogFont ne prend tient pas compte de la police d�finie dans les propri�t�s. Comment modifier cela ?
    Autre am�lioration facultative, comment modifier la liste d�roulante des Name pour la font, afin de n'afficher que les polices True Type ?

    3/ Autre am�lioration, j'ai quelques doutes sur la faisabilit� : permettre au d�veloppeur utilisant le composant de modifier graphiquement l'angle en rajoutant une Ancre au centre du label (de mani�re similiaire aux ancres pour aggrandir/r�duire).

    Voil�, d�sol� si je pose bcps de questions

    Note, si vous avez des commentaires, remarques, ou si vous voyez des horreures dans ce code, n'h�sitez pas � m'en faire part.

    Le <.h>
    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
     
    //Gard sébastien
    //Mai 2005
    #ifndef CustomLabelOrientableH
    #define CustomLabelOrientableH
    #include <SysUtils.hpp>
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <math.h>
    class PACKAGE TCustomLabelOrientable : public TCustomLabel
        {
        private:
            bool FVertical ;
            int FAngle ;
            LOGFONT LogFont ;
        protected:
            void __fastcall SetAngle(int angle) ;
            virtual void __fastcall AngleChanged() ;
            virtual void __fastcall Paint(void) ;
        public:
            __fastcall TCustomLabelOrientable(TComponent* Owner) ;
        __published:
            //Properties
            __property Align ;
            __property Anchors ;
            __property int Angle = {read=FAngle, write=SetAngle, default=0} ;
            __property AutoSize ;
            __property Caption ;
            __property Color ;
            __property Constraints ;
            __property Cursor ;
            __property DragCursor ;
            __property DragKind ;
            __property DragMode ;
            __property Enabled ;
            __property Font ;
            __property Height ;
            __property HelpContext ;
            __property HelpKeyword ;
            __property HelpType ;
            __property Hint ;
            __property Layout ;
            __property Left ;
            __property Name ;
            __property ParentColor ;
            __property ParentShowHint ;
            __property ShowHint ;
            __property Tag ;
            __property Top ;
            __property Transparent ;
            __property bool Vertical = {read=FVertical, write=FVertical, default=false} ;
            __property Visible ;
            __property Width ;
            __property WordWrap ;
     
            //Events
            __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 ;
        } ;
    #endif
    le <.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
     
    #include <vcl.h>
    #pragma hdrstop
    #include "CustomLabelOrientable.h"
    #pragma package(smart_init)
     
    static inline void ValidCtrCheck(TCustomLabelOrientable *)
        {
        new TCustomLabelOrientable(NULL) ;
        }
     
    namespace Customlabelorientable
        {
        void __fastcall PACKAGE Register()
            {
            TComponentClass classes[1] = {__classid(TCustomLabelOrientable)} ;
            RegisterComponents("Standard", classes, 0) ;
            }
        }
     
    __fastcall TCustomLabelOrientable::TCustomLabelOrientable(TComponent* Owner)
        : TCustomLabel(Owner)
        {
        AutoSize = false ;
        FVertical = false ;
     
        ZeroMemory(&LogFont, sizeof(LOGFONT)) ;
        SetAngle(0) ;
        }
     
    void __fastcall TCustomLabelOrientable::SetAngle(int angle)
        {
        if (angle < 0 || angle > 360)
            FAngle = 0 ;
        else
            FAngle = angle ;
     
        AngleChanged() ;
        }
     
    void __fastcall TCustomLabelOrientable::AngleChanged()
        {
        LogFont.lfEscapement = 10 * FAngle ;
        LogFont.lfOrientation = 10 * FAngle ;
        Invalidate() ;
        }
     
    void __fastcall TCustomLabelOrientable::Paint(void)
        {
        Canvas->Brush->Style = bsSolid ;
        Canvas->Brush->Color = Color ;
        Canvas->FillRect(Rect(0,0,Width,Height)) ;
     
        Canvas->Brush->Style = bsClear ;
        Canvas->Font->Handle = CreateFontIndirect(&LogFont) ;
     
        int centreVer = Height/2 ;
        int centreHor = Width/2 ;
        int angle = FAngle ;
     
        angle <= 180 ? angle += 180 : angle -= 180 ;
        angle -= Canvas->TextHeight(Caption)/2 ;
     
        double rad = M_PI * angle / 180.0 ;
        double rayon = Canvas->TextWidth(Caption)/2 ;
     
        int posVer =  centreVer - (sin(rad) * rayon) ;
        int posHor =  centreHor + (cos(rad) * rayon) ;
     
        Canvas->TextOut(posHor, posVer, Caption) ;
        }

  9. #9
    Membre �prouv�
    Homme Profil pro
    VP of Research and Innovation
    Inscrit en
    Mai 2002
    Messages
    84
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 54
    Localisation : Canada

    Informations professionnelles :
    Activit� : VP of Research and Innovation

    Informations forums :
    Inscription : Mai 2002
    Messages : 84
    Par d�faut
    Rapidement, je n'ai pas trop le temps aujourd'hui :

    Tu peux m'expliquer �a :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
        angle <= 180 ? angle += 180 : angle -= 180 ;
        angle -= Canvas->TextHeight(Caption)/2 ;
    Tu enl�ves la moiti� de la hauteur (en pixel) � l'angle (en degr�) ?
    Bizard ???

  10. #10
    Membre �clair� Avatar de Rodrigue
    Inscrit en
    Ao�t 2002
    Messages
    487
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2002
    Messages : 487
    Par d�faut
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    angle <= 180 ? angle += 180 : angle -= 180 ;
    Tu peux �crire �a comme :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    if (angle <= 180) angle += 180
    else                    angle -=180;
    Je pense que ce code doit servir � calculer l'angle dans le bon quadrant ?
    Apr�s soustraire � l'angle la moiti� de la hauteur tu texte Caption... soustraire une m�trique � un angle hum... enfin c'est plut�t une erreur de "notation". Je ne comprend pas non plus le but de ces deux lignes de code ...

    Pour le fonctionnement, le texte est centr� en
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    int centreVer = Height/2 ; 
        int centreHor = Width/2 ;
    o� Width et Height sont la largeur et la hauteur de la zone de dessin.

    Pour le calcul de posVert et de PosHor, ce n'est juste qu'un b�te triangle par rapport au centre du Canvas. Quoique moi je rajouterais p-e la demi-hauteur et la demi-largeur du texte � posVer et posHor respectivement...
    Lorsque l'angle est de 90, 180, 270 ou 360�, la LOGFONT prend un angle de 0�. Alors qu'un angle de 91� par exemple marche tr�s bien. Pourquoi ?
    Bon pour 360�, c'est normal!

  11. #11
    Membre averti

    Inscrit en
    Novembre 2004
    Messages
    17
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 17
    Par d�faut
    Ces 2 lignes servent � positionner le milieu du texte au centre du label. Comme un bon dessin vaut mieux qu'un long discours, ci-dessous l'effet avec et sans les 2 lignes de code.



    Effectivement, je pourrais rajouter la moiti� de la longeur et hauteur du texte apr�s le traitement � posVer et posHor comme le sugg�re Rodrigue plutot qu'utiliser ma mani�re.

    Par contre, en quoi l'utilisation de l'op�rateur ternaire (test ? : ) est une erreure de notation ?

  12. #12
    Membre �clair� Avatar de Rodrigue
    Inscrit en
    Ao�t 2002
    Messages
    487
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2002
    Messages : 487
    Par d�faut
    L'utilisation de l'op�rateur ternaire n'est pas une erreur. Je parlais d'erreur de notation en ce qui concerne la soustraction d'un angle avec un m�trique. Tu soustraies des poires et des pommes mais bon si �a fonctionne ...
    Comme tu le dis un dessin vaut mieux qu'un long discours :
    http://cjoint.com/?fDaAWKnJR3
    Le centre O (l� o� l'on va �crire le texte) est de coordonn�es :
    O := (Ox, Oy) = (centre_x - largeur/2, centre_y + hauteur/2)
    Tu as donc les coordonn�es d'un vecteur auquel tu vas effectuer une rotation 2D. Pour rappel, les nouvelles coordonn�es se calculent de cette fa�on :
    x' = x * cos(A) + y * sin(A);
    y' = -x * sin(A) + y * cos(A);
    Tu as donc que le nouveau point O' vaut :
    O' =Ox* cos(Angle) + Oy * sin(Angle);
    y' = -Ox * sin(Angle) + Oy * cos(Angle);
    Voil� en esp�rant avoir pu solutionner ton probl�me...

    Cordialement,
    Rodrigue

  13. #13
    Membre averti

    Inscrit en
    Novembre 2004
    Messages
    17
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 17
    Par d�faut
    J'ai modifi� cette partie de code
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
        int centreVer = Height/2 ;
        int centreHor = Width/2 ;
        int angle = FAngle ;
     
        angle <= 180 ? angle += 180 : angle -= 180 ;
        angle -= Canvas->TextHeight(Caption)/2 ;
     
        double rad = M_PI * angle / 180.0 ;
        double rayon = Canvas->TextWidth(Caption)/2 ;
     
        int posVer =  centreVer - (sin(rad) * rayon) ;
        int posHor =  centreHor + (cos(rad) * rayon) ;
    Par celle-ci, en utilisant ta mani�re de faire
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
        int posX = Width/2 - Canvas->TextWidth(Caption)/2 ;
        int posY = Height/2 + Canvas->TextHeight(Caption)/2 ;
     
        int posXfinal = posX * cos(FAngle) + posY * sin(FAngle) ;
        int posYfinal = -posX * cos(FAngle) + posY * sin(FAngle) ;
    Oui, c'est beaucoup plus propre, mais malheureusement, ca marche moins bien. La coordonn� O(x,y) du texte n'�volue plus du tout de mani�re circulaire autour du centre du label, et je me retrouve avec un texte positionn� un peu n'importe comment � l'interieur de l'espace du label.

    Est-ce du � une erreur de ma part dans l'impl�mentation de ton explication ?

  14. #14
    Membre �clair� Avatar de Rodrigue
    Inscrit en
    Ao�t 2002
    Messages
    487
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2002
    Messages : 487
    Par d�faut
    Est-ce du � une erreur de ma part dans l'impl�mentation de ton explication ?
    Oui !

    O := (Ox, Oy) = (centre_x - largeur/2, centre_y + hauteur/2)
    Ox' =Ox* cos(Angle) + Oy * sin(Angle);
    Oy' = -Ox * sin(Angle) + Oy * cos(Angle);
    Le point O est le point o� tu vas �crire le texte ...
    centre, ce le point milieu de ton canvas
    donc centre_x = width/2 et centre_y = height/2
    largeur c'est la largeur de ton texte d'o� TextWidth
    longueur c'est la longueur de ton texte d'o� TextHeight
    Angle c'est la valeur de l'angle qui fait pivoter ton texte ...

    J'ai fait l'exemple qui fonctionne. Je vais le publier dans les sources BCB. J'attends une r�ponse pour savoir comment proc�der...

    Cordialement,
    Rodrigue

  15. #15
    Membre averti

    Inscrit en
    Novembre 2004
    Messages
    17
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 17
    Par d�faut
    Merci pour l'explication, mais finalement le probl�me �tait tout autre

    Apr�s une bonne prise de t�te avec un de mes anciens profs, on a identifi� la source :

    L'erreur provient de la structure LOGFONT elle-m�me qui doit fonctionner par quartier et qui ne g�re pas (ou bug) les angles 90, 180 et 270�.

    La solution est simple, comme la propri�t� lfEscapement est en dixi�me de degr�, il suffit de rajouter +1 � celle-ci. Par exemple pour un angle de 90�, celui ci devient �gale � 901 dixi�mes de degr�s. Imperceptible par l'oeil, mais ca �vite le bug.

    1 semaine de posts pour r�soudre un bug dont je ne suis m�me pas l'auteur... merci Microsoft

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
        LogFont.lfEscapement = 10 * FAngle +1  ;
        LogFont.lfOrientation = 10 * FAngle +1 ;

    Par contre il me reste toujours 2 questions en suspend :

    1) Comment modifier la liste des polices disponibles affich�es dans l'�diteur de propri�t�, afin de ne garder que les True Type. Et comment faire le lien entre le choix du d�veloppeur et ce qui est affich�.
    Peut etre avec ceci ?

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Canvas->Font->Name = Font->Name
    2) Est-il possible de modifier l'angle graphiquement au moyen d'une nouvelle ancre sur le label ?

    Merci encore pour tout le mal que vous vous donnez

  16. #16
    Membre �m�rite
    Inscrit en
    Juin 2005
    Messages
    644
    D�tails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Par d�faut
    la librairie LMD tools pour Delphi ET Borland C++ offre des label orientables.
    La version compl�te est payante, une version lmd tools 7 se existe et est gratuite downloadable du web.

    http://www.lmdtools.com/

  17. #17
    Membre averti

    Inscrit en
    Novembre 2004
    Messages
    17
    D�tails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 17
    Par d�faut
    Encore merci � tous pour votre aide. J'ai termin� mon composant.

    Si on veut faire plus, il y a toujours de quoi faire, mais la version actuelle quoique imparfaite (p.ex pour les fonts) me convient. (Et surtout l'�ch�ance approche ) Je clos donc le sujet.

    Ci dessous le code source complet si ca peut aider des gens par la suite :

    <.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
     
    //Date : 8 juin 05
    //Auteurs : Gard Sébastien - Martin Grégory
    #include <vcl.h>
    #pragma hdrstop
    #include "CustomLabelOrientable.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(TCustomLabelOrientable *)
        {
        new TCustomLabelOrientable(NULL) ;
        }
     
    namespace Customlabelorientable
        {
        void __fastcall PACKAGE Register()
            {
            TComponentClass classes[1] = {__classid(TCustomLabelOrientable)} ;
            RegisterComponents("Standard", classes, 0) ;
            }
        }
     
    __fastcall TCustomLabelOrientable::TCustomLabelOrientable(TComponent* Owner)
        : TCustomLabel(Owner)
        {
        AutoSize = true ;
        FAngle = 0 ;
        //Si la font Tahoma n'est pas disponible sur le système, la structure
        //LogFont utilise par défaut une autre police valable
        FFontName = "Tahoma" ;
        FFontColor = clBlack ;
        FFontHeight = 16 ;
        FFontBold = FW_NORMAL ;
        FFontItalic = false ;
        FFontStrikeOut = false ;
        FFontUnderline = false ;
     
        //Créé dynamiquement la liste des fonts disponible sur le système
        FFontNameList = new TStringList() ;
        for (int i = 0 ; i < Screen->Fonts->Count ; i++)
            FFontNameList->Add(Screen->Fonts->Strings[i]) ;
     
        //Remplit l'espace mémoire utilisé par l'objet LogFont de zéros
        ZeroMemory(&LogFont, sizeof(LOGFONT)) ;
        //Affecte rééllement les propriétés définies plus haut à l'objet LogFont
        LogFontChanged() ;
        }
     
    __fastcall TCustomLabelOrientable::~TCustomLabelOrientable()
        {
        delete FFontNameList ;
        }
     
    void __fastcall TCustomLabelOrientable::SetAngle(unsigned int angle)
        {
        if (angle >= 360)
            FAngle = 0 ;
        else
            FAngle = angle ;
     
        LogFontChanged() ;
        }
     
    void __fastcall TCustomLabelOrientable::SetFontName(AnsiString name)
        {
        //Vérifie que le nom de la font existe bien sur le système.
        int i = 0 ;
        bool found = false ;
        while (i < FFontNameList->Count && found == false)
            {
            if (name == FFontNameList->Strings[i])
                found = true ;
            i++ ;
            }
     
        if (found == true)
            {
            FFontName = name ;
            LogFontChanged() ;
            }
        }
     
    TStrings* __fastcall TCustomLabelOrientable::GetFontNameList()
        {
        return FFontNameList ;
        }
     
    void __fastcall TCustomLabelOrientable::SetFontNameList(TStrings *list)
        {
        FFontNameList->Assign(list) ;
        }
     
    void __fastcall TCustomLabelOrientable::SetFontColor(TColor color)
        {
        FFontColor = color ;
        LogFontChanged() ;
        }
     
    void __fastcall TCustomLabelOrientable::SetFontHeight(unsigned int height)
        {
        FFontHeight = height ;
        LogFontChanged() ;
        }
     
    bool __fastcall TCustomLabelOrientable::GetFontBold()
        {
        if (FFontBold == FW_BOLD)
            return true ;
        else
            return false ;
        }
     
    void __fastcall TCustomLabelOrientable::SetFontBold(bool state)
        {
        state == true ? FFontBold = FW_BOLD : FFontBold = FW_NORMAL ;
        LogFontChanged() ;
        }
     
    void __fastcall TCustomLabelOrientable::SetFontItalic(bool state)
        {
        FFontItalic = state ;
        LogFontChanged() ;
        }
     
    void __fastcall TCustomLabelOrientable::SetFontStrikeOut(bool state)
        {
        FFontStrikeOut = state ;
        LogFontChanged() ;
        }
     
    void __fastcall TCustomLabelOrientable::SetFontUnderline(bool state)
        {
        FFontUnderline = state ;
        LogFontChanged() ;
        }
     
    //Applique les propriétés à l'objet LogFont, utilisé pour dessiner le texte
    void __fastcall TCustomLabelOrientable::LogFontChanged()
        {
        //Choix du nom de la police. Le nom (lfFaceName)est un tableau de char,
        //il est nécessaire d'effectuer ces opérations pour utiliser l'AnsiString
        //de la propriété FFontName
        char f[32] ;
        strcpy(f, FFontName.c_str()) ;
        strcpy(LogFont.lfFaceName, f) ;
     
        //L'angle est en 10ème de degré. A cause d'une erreur ou d'une mauvaise
        //gestion dans la structure, les angles de 90, 180 et 270 degrés ne sont
        //pas appliqués (le résultat est similaire à un angle de 0°), il faut
        //ajouter +1 à la valeur passée. Le résultat donne 901 dixième de degrés. La
        //différence est imperceptible à l'oeil nu, mais évite le bug.
        //Pour une meilleure solution, il faudrait avoir accès au code source
        //de cette structure (fichier d'en-tête wingdi.h)
        LogFont.lfEscapement = 10 * FAngle +1  ;
        LogFont.lfOrientation = 10 * FAngle +1 ;
        LogFont.lfHeight = FFontHeight ;
        LogFont.lfWeight = FFontBold ;
        LogFont.lfItalic = FFontItalic ;
        LogFont.lfStrikeOut = FFontStrikeOut ;
        LogFont.lfUnderline = FFontUnderline ;
     
        Invalidate() ;
        }
     
    void __fastcall TCustomLabelOrientable::Paint(void)
        {
        //Clear le label en redessinant une rectangle par dessus
        Canvas->Brush->Style = bsSolid ;
        Canvas->Brush->Color = Color ;
        Canvas->FillRect(Rect(0,0,Width,Height)) ;
     
        Canvas->Brush->Style = bsClear ;
        //Créé une Font avec les caractéristiques de LogFont et la passe au Canvas
        Canvas->Font->Handle = CreateFontIndirect(&LogFont) ;
        Canvas->Font->Color = FFontColor ;
     
        int longueurCaption = Canvas->TextWidth(Caption) ;
        int hauteurCaption = Canvas->TextHeight(Caption) ;
        //converti l'angle en radian pour utiliser les méthodes cos et sin de math.h
        double rad = M_PI * FAngle / 180.0 ;
     
        //Ajuste la taille du label en hauteur et largeur à la taille du texte
        if (AutoSize == true)
            {
            //On ajoute +1 à cause de la convertion du résultat, nombre à virgule,
            //en entier tel que demandé par la propriété Width et Height
            Width = abs(cos(rad) * longueurCaption) +
                abs(cos(M_PI * (90+FAngle) / 180.0) * hauteurCaption) +1 ;
     
            Height = abs(sin(rad) * longueurCaption) +
                abs(sin(M_PI * (90+FAngle) / 180.0) * hauteurCaption) +1 ;
            }
     
        //Défini les coordonnées X et Y à partir d'où sera dessiné le texte afin de
        //l'avoir parfaitement centré dans le label, quel que soit son angle et sa
        //taille
        int posHor = Width/2.0 - (cos(rad) * longueurCaption/2.0) -
                (sin(rad) * hauteurCaption/2.0) ;
        int posVer = Height/2.0 - (cos(rad) * hauteurCaption/2.0) +
                (sin(rad) * longueurCaption/2.0) ;
     
        //Dessine le texte
        Canvas->TextOut(posHor, posVer, Caption) ;
        }
    <.h>
    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
     
    #ifndef CustomLabelOrientableH
    #define CustomLabelOrientableH
    #include <SysUtils.hpp>
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <math.h>
     
    class PACKAGE TCustomLabelOrientable : public TCustomLabel
        {
        private:
            unsigned int FAngle ;
     
            AnsiString FFontName ;
            //Liste des polices disponibles sur le système, à vocation indicative
            TStringList* FFontNameList ;
            TColor FFontColor ;
            unsigned int FFontHeight ;
            unsigned int FFontBold ;
            bool FFontItalic ;
            bool FFontStrikeOut ;
            bool FFontUnderline ;
     
            LOGFONT LogFont ; // Windows native font structure
        protected:
            virtual void __fastcall SetAngle(unsigned int angle) ;
            virtual void __fastcall SetFontName(AnsiString name) ;
            virtual TStrings* __fastcall GetFontNameList() ;
            virtual void __fastcall SetFontNameList(TStrings *list);
            virtual void __fastcall SetFontColor(TColor color) ;
            virtual void __fastcall SetFontHeight(unsigned int height) ;
            virtual bool __fastcall GetFontBold() ;
            virtual void __fastcall SetFontBold(bool state) ;
            virtual void __fastcall SetFontItalic(bool state) ;
            virtual void __fastcall SetFontStrikeOut(bool state) ;
            virtual void __fastcall SetFontUnderline(bool state) ;
     
            virtual void __fastcall LogFontChanged() ;
            virtual void __fastcall Paint(void) ;
        public:
            __fastcall TCustomLabelOrientable(TComponent* Owner) ;
            virtual __fastcall ~TCustomLabelOrientable() ;
        __published:
            //Properties
            __property Align ;
            __property Anchors ;
            __property unsigned int Angle = {read=FAngle, write=SetAngle, default=0} ;
            __property AutoSize ;
            __property Caption ;
            __property Color ;
            __property Constraints ;
            __property Cursor ;
            __property DragCursor ;
            __property DragKind ;
            __property DragMode ;
            __property Enabled ;
            __property AnsiString FontName = {read=FFontName, write=SetFontName} ;
            __property TStrings *FontNameList = {read=GetFontNameList, write=SetFontNameList} ;
            __property unsigned int FontHeight = {read=FFontHeight, write=SetFontHeight, default=16} ;
            __property TColor FontColor = {read=FFontColor, write=SetFontColor, default=clBlack	} ;
            __property bool FontBold = {read=GetFontBold, write=SetFontBold, default=0} ;
            __property bool FontItalic = {read=FFontItalic, write=SetFontItalic, default=0} ;
            __property bool FontStrikeOut = {read=FFontStrikeOut, write=SetFontStrikeOut, default=0} ;
            __property bool FontUnderline = {read=FFontUnderline, write=SetFontUnderline, default=0} ;
            __property Height ;
            __property HelpContext ;
            __property HelpKeyword ;
            __property HelpType ;
            __property Hint ;
            __property Layout ;
            __property Left ;
            __property Name ;
            __property ParentColor ;
            __property ParentShowHint ;
            __property ShowHint ;
            __property Tag ;
            __property Top ;
            __property Transparent ;
            __property Visible ;
            __property Width ;
            __property WordWrap ;
     
            //Events
            __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 ;
        } ;
    #endif

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Cherche pistes pour d�marrer
    Par StringBuilder dans le forum Android
    R�ponses: 15
    Dernier message: 16/07/2012, 12h41
  2. Debutant en C cherche aide pour fonctions!!!!
    Par benji17c dans le forum C
    R�ponses: 5
    Dernier message: 30/09/2003, 12h47
  3. R�ponses: 3
    Dernier message: 01/07/2003, 16h04
  4. Cherche conseil pour choisir mon orientation.
    Par AslDice dans le forum D�buter
    R�ponses: 6
    Dernier message: 24/04/2003, 17h07
  5. [Kylix] cherche composants pour les sockets
    Par coriolis dans le forum EDI
    R�ponses: 1
    Dernier message: 09/04/2003, 10h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo