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

API, COM et SDKs Delphi Discussion :

Centrer verticalement un texte dans un Canvas


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 245
    Points : 154
    Points
    154
    Par défaut Centrer verticalement un texte dans un Canvas
    Bonjour,

    Je voudrai savoir s'il y a un moyen de Centrer verticalement du texte dans un Canvas. J'ai un rectangle et je voudrai m'assurer que le libelle de ce rectangle soit toujours centre et horizontalement et verticalement. Je precise que le libelle peut etre sur 2 ou 3 lignes.
    Merci.

    ::

  2. #2
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Canvas.TextWidth( TonTexte )
    et
    Canvas.TextHeight( TonTexte )
    te permettra de centre ton texte à l'aide des dimensions de ton canvas

    du style ( attention, c plus de l'algo que du code)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    X = ( Width - TextWidth ) / 2 
    et
    Y = ( Height - TextHeight ) / 2
    a adapter
    Section Delphi
    La mine d'or: La FAQ, les Sources

    Un développement compliqué paraitra simple pour l'utilisateur, frustrant non ?
    Notre revanche ? l'inverse est aussi vrai ;-)

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 245
    Points : 154
    Points
    154
    Par défaut
    Citation Envoyé par TicTacToe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Canvas.TextWidth( TonTexte )
    et
    Canvas.TextHeight( TonTexte )
    te permettra de centre ton texte à l'aide des dimensions de ton canvas

    du style ( attention, c plus de l'algo que du code)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    X = ( Width - TextWidth ) / 2 
    et
    Y = ( Height - TextHeight ) / 2
    a adapter
    Je ne comprends pas comment ton code peut m'aider. Merci quand meme

  4. #4
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bsr,

    Voici la procédure (simplifiée) que j'utilise :

    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
    unit UnitDrawText;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, Mask;
     
    type
      TVerticalAlignment = (tvaTop, tvaBottom, tvaCenter);
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
     
    procedure DrawText(Canvas : TCanvas; ARect : TRect; Text : String;
      HAlignment : TAlignment; VAlignment : TVerticalAlignment;
      WordWrap : Boolean = False);
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
     
    procedure DrawText(Canvas : TCanvas; ARect : TRect; Text : String;
      HAlignment : TAlignment; VAlignment : TVerticalAlignment;
      WordWrap : Boolean = False);
    var
      Flags : Integer;
      dX, dY : Integer;
      TextRect : TRect;
    begin
      if Canvas=nil then Exit;
     
      TextRect := ARect;
     
      // Ajuste les dimensions de TextRect pour faire tenir le texte
      Flags := DT_NOPREFIX or DT_CALCRECT;
      Windows.DrawText(Canvas.Handle,PChar(Text),Length(Text),TextRect,Flags);
     
      // Ajuste les dimensions de Result en fonction des alignements
      // horizontal et vertical
      dX := 0;
      if HAlignment=taCenter then
        dX := ((ARect.Right-ARect.Left)-(TextRect.Right-TextRect.Left)) div 2;
     
      if HAlignment=taRightJustify then
        dX := ((ARect.Right-ARect.Left)-(TextRect.Right-TextRect.Left))-1;
     
      dY := 0;
      if VAlignment=tvaCenter then
        dY := ((ARect.Bottom-ARect.Top)-(TextRect.Bottom-TextRect.Top)) div 2;
     
      if VAlignment=tvaBottom then
        dY := (ARect.Bottom-ARect.Top)-(TextRect.Bottom-TextRect.Top);
     
      OffsetRect(TextRect,dX,dY);
     
     
      Flags := DT_NOPREFIX;
     
      case HAlignment of
        taLeftJustify : Flags := Flags or DT_LEFT;
        taRightJustify : Flags := Flags or DT_RIGHT;
        taCenter : Flags := Flags or DT_CENTER;
      end;
      if WordWrap then Flags := Flags or DT_WORDBREAK;
     
      Windows.DrawText(Canvas.Handle,PChar(Text),Length(Text),TextRect,Flags);
     
    end;
     
     
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      ARect : TRect;
    begin
      ARect := Bounds(10,10,100,50);
      Canvas.Brush.Color := clRed;
      Canvas.FrameRect(ARect);
      Canvas.Brush.Style := bsClear;
      DrawText(Canvas,ARect,'Demo',taCenter,tvaCenter,True);
    end;
     
    end.

    Cette fonction permet de dessiner un texte dans une zone rectangulaire d'un canevas.

    Nota : le texte peut déborder de la zone s'il est trop grand ! Si dans ce cas le texte qui "déborde" ne doit pas être affiché alors il faut faire du clipping...

    @+
    Php


    PS : j'avais pas vu la réponse de Waskol http://www.developpez.net/forums/viewtopic.php?t=464439
    @+
    Php

    D7 Enterprise - XP sp2
    The Truth is Out There

  5. #5
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut


    En effet tu aurais trouvé ce code (qui sera publié dans la prochaine mise à jour de la FAQ ) :

    Comment dessiner un texte multiligne, correctement justifié et aligné dans une zone particulière d'un Canvas

    Qui n'a jamais rencontré le problème de savoir comment écrire un texte qui plus est multiligne, bien centré dans une zone particulière d'un canvas ?
    L'utilisation de la méthode TCanvas.TextOut (trop limitée ?) ou de la fonction DrawText de l'API Windows (trop complexe ?) se révèle être décourageante pour qui souhaite par exemple afficher un texte de 3 lignes dans la cellule d'un TStringGrid.

    La fonction suivante utilise la fonction TextSize déjà décrite dans l'une de nos FAQs : Comment connaître la largeur et la hauteur en pixels d'un texte ?


    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
    interface
    ...
    type
      TAlignementVertical=(alVTop,alVCenter,alVBottom);
      TAlignementHorizontal=(alHLeft,alHCenter,alHRight);
      TJustification=(JustLeft,JustCenter,JustRight);
      procedure DessineTexteMultiligne(AString:string;ACanvas:TCanvas;ARect: TRect;
                           AlignementHorizontal:TAlignementHorizontal;
                           AlignementVertical:TAlignementVertical;
                           TextJustification:TJustification);
    ...
    implementation
     
    //Voir FAQ Delphi de www.developpez.com pour cette fonction :
    //URL : http://delphi.developpez.com/faq/?page=typechaine#dimensionstexte
    Function TextSize(Phrase : string; Police : TFont = nil) : TPoint;
    var
      DC: HDC;
      X: Integer;
      Rect: TRect;
      C : TBitmap;
    begin
      C := TBitmap.create;
      if police <> nil then  C.canvas.Font := police;
     
        Rect.Left := 0;
        Rect.Top:=0;
        Rect.Right:=0;
        Rect.Bottom:=0;
        DC := GetDC(0);
        C.Canvas.Handle := DC;
        DrawText(C.Canvas.Handle, PChar(Phrase), -1, Rect, (DT_EXPANDTABS or DT_CALCRECT));
        C.Canvas.Handle := 0;
        ReleaseDC(0, DC);
        result.X:=Rect.Right-Rect.Left;
        result.Y:=Rect.Bottom-Rect.Top;
        C.Free;
    end;
     
    //Notre procedure d'affichage de texte multiligne
    procedure DessineTexteMultiligne(AString: string;ACanvas:TCanvas;ARect: TRect;
                           AlignementHorizontal:TAlignementHorizontal;
                           AlignementVertical:TAlignementVertical;
                           TextJustification:TJustification);
    var
      AHeight,AWidth:integer;
      Rect,oldClipRect:TRect;
      ATop,ALeft,H,W:Integer;
      AText:string;
      JustificationDuTexte:Integer;
      MyRgn:HRGN;
    begin
      with ACanvas do
      begin
        Lock;
        AHeight:=ARect.Bottom-ARect.Top;
        AWidth:=ARect.Right-ARect.Left;
        //on calcule la taille du rectangle dans lequel va tenir le texte
        W:=TextSize(AString,ACanvas.Font).X;
        H:=TextSize(AString,ACanvas.Font).Y;
     
        //on calcule la position (Haut,Gauche) du rectangle dans lequel va tenir le texte
        //en fonction de l'alignement horizontal et vertical choisis
        ATop:=ARect.Top;
        ALeft:=ARect.Left;
     
     
        case AlignementVertical of
          alVBottom : ATop:=ARect.Bottom-H;
          alVCenter : ATop:=ARect.Top+((AHeight-H) div 2);
          alVTop    : ATop:=ARect.Top;
        end;
     
        case AlignementHorizontal of
          alHLeft  : ALeft:=ARect.Left;
          alHCenter: ALeft:=ARect.Left+(AWidth-W) div 2;
          alHRight : ALeft:=ARect.Right-W;
        end;
     
        //Fin du calcul du rectangle, on met le resultat dans Rect
        Rect:=Bounds(ALeft,ATop,W,H);
     
        //On rempli le rectangle de la zone sinon on voit le texte que delphi à dessiné
        FillRect(ARect);
     
        //On détermine les paramètres de justification à passer à Windows
        case TextJustification of
          JustLeft  : JustificationDuTexte:=DT_LEFT;
          JustCenter: JustificationDuTexte:=DT_CENTER;
          JustRight : JustificationDuTexte:=DT_RIGHT;
        end;
     
        //Si le texte est plus grand que notre zone, on prend cette précaution (Clipping)
        with ARect do MyRgn :=CreateRectRgn(Left,Top,Right,Bottom);
        SelectClipRgn(Handle,MyRgn);
     
        //On dessine le texte
        DrawText(Handle,PChar(AString),-1,Rect,JustificationDuTexte or DT_NOPREFIX or DT_WORDBREAK );
     
        //On a plus besoin de la zone de clipping
        SelectClipRgn(Handle,0);
        DeleteObject(MyRgn);
        Unlock;
      end;
    end;
    Utilisation de la procédure DessineTexteMultiligne :
    • AString: string;
      Chaîne de caractère à dessiner.
    • ACanvas:TCanvas;
      Canvas où le texte doit être dessiné
    • ARect: TRect;
      Zone rectangulaire du Canvas dans laquelle le texte doit être dessiné
    • AlignementHorizontal:TAlignementHorizontal;
      Alignement Horizontal du texte dans la zone rectangulaire, trois options sont possibles :
      [list:94e872cfb7]
    • alHLeft : Place le texte à gauche dans la zone rectangulaire.
    • alHCenter : Centre le texte horizontalement dans la zone rectangulaire.
    • alHRight : Place le texte à droite dans la zone rectangulaire.
    [*]AlignementVertical:TAlignementVertical;
    Alignement Vertical du texte dans la zone rectangulaire, trois options sont possibles :
    • alVTop : Place le texte en haut de la zone rectangulaire.
    • alVCenter : Centre le texte verticalement dans la zone rectangulaire.
    • alVBottom : Place le texte en bas de la zone rectangulaire.
    [*]TextJustification:TJustification
    Justification du texte
    • JustLeft : Justifie le texte à gauche
    • JustCenter : Justification centrée du texte
    • JustRight : Justifie le texte à droite
    [/list:u:94e872cfb7]

    Note concernant le choix du type des paramètres de la procédure :
    L'utilisation des types déjà existants de Delphi est tout aussi valable, à savoir :
    • AlignementVertical:TTextLayout;
    • AlignementHorizontal:TAlignement;
    • TextJustification:TAlignment;

    Ces types sont déclarés dans les unités StdCtrls et Classes.
    Bon dev
    Bidouilleuse Delphi

  6. #6
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 245
    Points : 154
    Points
    154
    Par défaut
    Merci pour le code.
    Mais juste une petite remarque, cela fonctionne que si je n'est qu'une seule ligne courte (qui n'excede pas la largeur du canvas) ou qu'on formatte nous meme le texte en plusieurs lignes (en y ajoutant #10 et #13). Ca serait plus interessant que ca soit le code qui gere tout ca: Si j'ai un long texte, c'est au code d'aller a la nouvelle ligne et de respecter l'alignement, la justification, etc...
    Est-ce trop exigeant??

  7. #7
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Pour la mise en forme, tu peux utiliser un memo invisible avec wordwrap utilisant la même police et de largeur identique à la zone de destination.
    Tu affectes le texte au memo via la propriéte text des lines du Memo et tu récupéres les lignes (memo1.lines[i]).
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 132
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 132
    Points : 1 418
    Points
    1 418
    Par défaut
    Citation Envoyé par Ben_Le_Cool
    Merci pour le code.
    Mais juste une petite remarque, cela fonctionne que si je n'est qu'une seule ligne courte (qui n'excede pas la largeur du canvas) ou qu'on formatte nous meme le texte en plusieurs lignes (en y ajoutant #10 et #13). Ca serait plus interessant que ca soit le code qui gere tout ca: Si j'ai un long texte, c'est au code d'aller a la nouvelle ligne et de respecter l'alignement, la justification, etc...
    Est-ce trop exigeant??
    Bonjour,

    Dans l'aide en ligne, tu peux trouver les autres options de la fonction API DrawText()

    Entre autre, tu verras DT_SINGLELINE qu'il faut désactiver pour que le texte passe automatiquement à la ligne si il est trop long.

    Il y a également DT_CALCRECT qui permet de demander un recalcul du rectangle passé en paramètre pour afficher "au mieux" le texte.
    Une fois récupéré le nouveau rectangle de dessin, il ne te reste plus qu'à le centrer verticalement.

    Il faut donc faire appel à DrawText() 2 fois. (la première avec DT_CALCRECT pour obtenir le rectangle de dessin, la seconde pour dessiner ton texte)


    devYan.

  9. #9
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bsr,

    Exact c'est tout à fait possible toujour en utilisant l'API avec DT_WORDBREAK en plus et surtout en fournissant un rectangle avec la largeur voulue pour le texte : la hauteur par contre n'a pas d'importance (mieux vaut qd même qu'elle ne soit pas nulle)



    Ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     Text := 'Ce test est bien trop long et des retours à la ligne seront automatiquement insérés ! C'est pas beau le progrès ?';
     
      // On veut absolument que le texte tienne dans un rectangle de 100 pixels de large (la hauteur est ignorée car elle va être recalculée)
      TextRect := Bounds(0,0,100,10);
    // Ajuste les dimensions de TextRect pour faire tenir le texte 
      Flags := DT_NOPREFIX or DT_CALCRECT or DT_WORDBREAK; 
      Windows.DrawText(Canvas.Handle,PChar(Text),Length(Text),TextRect,Flags);
    Ne pas oublier sous Delphi (au moins sous D7) : [Aide][SDK Windows] puis onglet [Index] et rechercher DrawText : tout y est !


    @+
    Php
    @+
    Php

    D7 Enterprise - XP sp2
    The Truth is Out There

  10. #10
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par Ben_Le_Cool
    Merci pour le code.
    Mais juste une petite remarque, cela fonctionne que si je n'est qu'une seule ligne courte (qui n'excede pas la largeur du canvas) ou qu'on formatte nous meme le texte en plusieurs lignes (en y ajoutant #10 et #13). Ca serait plus interessant que ca soit le code qui gere tout ca: Si j'ai un long texte, c'est au code d'aller a la nouvelle ligne et de respecter l'alignement, la justification, etc...
    Est-ce trop exigeant??
    On me cherche là, hein ?

    Bon, allez, zoup, voici le code qui le fait !
    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
    //La valeur du paramètre AWidth détermine si on effectue unretour
    //à la ligne automatique ou non :
    //    - avec AWidth=0 => pas de WordWrap
    //    - avec AWidth<>0 => WorWrap sur la largeur donnée
    Function TextSize(Phrase : string; AWidth:integer; Police : TFont = nil) : TPoint;
    var
      DC: HDC;
      X: Integer;
      Rect: TRect;
      C : TBitmap;
      WordWrapParams:integer;
    begin
      C := TBitmap.create;
      if police <> nil then  C.canvas.Font := police;
     
        Rect.Left := 0;
        Rect.Top:=0;
        Rect.Right:=AWidth;
        Rect.Bottom:=0;
        DC := GetDC(0);
        C.Canvas.Handle := DC;
     
        WordWrapParams:=0;
        if AWidth<>0 then WordWrapParams:=DT_NOCLIP or DT_NOPREFIX or DT_WORDBREAK;
     
        DrawText(C.Canvas.Handle, PChar(Phrase), -1, Rect, WordWrapParams or (DT_EXPANDTABS or DT_CALCRECT));
        C.Canvas.Handle := 0;
        ReleaseDC(0, DC);
        result.X:=Rect.Right-Rect.Left;
        result.Y:=Rect.Bottom-Rect.Top;
        C.Free;
    end;
     
    //Notre procedure d'affichage de texte multiligne
    procedure DessineTexteMultiligne(AString: string; WordWrap:boolean;ACanvas:TCanvas;ARect: TRect;
                           AlignementHorizontal:TAlignementHorizontal;
                           AlignementVertical:TAlignementVertical;
                           TextJustification:TJustification);
    var
      AHeight,AWidth:integer;
      Rect,oldClipRect:TRect;
      ATop,ALeft,H,W:Integer;
      AText:string;
      JustificationDuTexte:Integer;
      MyRgn:HRGN;
      APoint:TPoint;
    begin
      with ACanvas do
      begin
        Lock;
        AHeight:=ARect.Bottom-ARect.Top;
        AWidth:=ARect.Right-ARect.Left;
        //on calcule la taille du rectangle dans lequel va tenir le texte (sans WordWrap)
        APoint:=TextSize(AString,0,ACanvas.Font);
        W:=APoint.X;
        H:=APoint.Y;
     
        //on calcule la position (Haut,Gauche) du rectangle dans lequel va tenir le texte
        //en fonction de l'alignement horizontal et vertical choisis
        ATop:=ARect.Top;
        ALeft:=ARect.Left;
     
        If WordWrap then //Si on veut un "WordWrap" (retour à la ligne automatique)
          if W>(ARect.Right-ARect.Left) then //et que le texte dépasse du rectangle de destination
          begin //alors...
            W:=(ARect.Right-ARect.Left); //on fixe la largeur du texte
            H:=TextSize(AString,W,ACanvas.Font).y; //on recalcule la hauteur du texte
          end;
     
        case AlignementVertical of
          alVBottom : ATop:=ARect.Bottom-H;
          alVCenter : ATop:=ARect.Top+((AHeight-H) div 2);
          alVTop    : ATop:=ARect.Top;
        end;
     
        case AlignementHorizontal of
          alHLeft  : ALeft:=ARect.Left;
          alHCenter: ALeft:=ARect.Left+(AWidth-W) div 2;
          alHRight : ALeft:=ARect.Right-W;
        end;
     
        //Fin du calcul du rectangle, on met le resultat dans Rect
        Rect:=Bounds(ALeft,ATop,W,H);
     
        //On rempli le rectangle de la zone sinon on voit le texte que delphi à dessiné
        FillRect(ARect);
     
        //On détermine les paramètres de justification à passer à Windows
        case TextJustification of
          JustLeft  : JustificationDuTexte:=DT_LEFT;
          JustCenter: JustificationDuTexte:=DT_CENTER;
          JustRight : JustificationDuTexte:=DT_RIGHT;
        end;
     
        //Si le texte est plus grand que notre zone, on prend cette précaution (Clipping)
        with ARect do MyRgn :=CreateRectRgn(Left,Top,Right,Bottom);
        SelectClipRgn(Handle,MyRgn);
     
        //On dessine le texte
        DrawText(Handle,PChar(AString),-1,Rect,JustificationDuTexte or DT_NOCLIP or DT_NOPREFIX or DT_WORDBREAK );
     
        //On a plus besoin de la zone de clipping
        SelectClipRgn(Handle,0);
        DeleteObject(MyRgn);
        Unlock;
      end;
    end;
    Bidouilleuse Delphi

  11. #11
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bsr Waskol

    Pouvoir passer par ex TextWordBreak en tant que paramètre supplémentaire à la fct DessineTexteMultiligne() aurait été la cerise sur le gâteau !

    Mais bon c'est vrai je chippote un peu là

    @+
    Php
    @+
    Php

    D7 Enterprise - XP sp2
    The Truth is Out There

  12. #12
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Reregarde, mon code dans 1 minute...
    Bidouilleuse Delphi

  13. #13
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Ca y'est....

    La cerise est sur le gateau (avec plein de crême en plus !)



    Si quelqu'un à des idées pour la justification verticale du texte un peu comme ça :
    Première ligne

    Deuxième ligne

    Dernière ligne
    ..je suis preneur...
    Bidouilleuse Delphi

  14. #14
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Quel talent Ca devient presqu'un chat interractif ce forum !

    Garre à celui qui ne sait pas aligner correctement un texte à l'écran désormais !

    Vous voilà prévenus !


    @+
    Php
    @+
    Php

    D7 Enterprise - XP sp2
    The Truth is Out There

  15. #15
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 245
    Points : 154
    Points
    154
    Par défaut
    C'est mieux maintenant, mais reste juste un petit detail pour que ca soit parfait (oui, oui, je sais je suis trop exigeant ).
    Si mon texte est trop large pour le canvas, j'ai essaye d'ajouter l'option DT_END_ELLIPSIS a ton code, mais ca n'a pas marche.
    ::

  16. #16
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par Ben_Le_Cool
    C'est mieux maintenant, mais reste juste un petit detail pour que ca soit parfait (oui, oui, je sais je suis trop exigeant ).
    Si mon texte est trop large pour le canvas, j'ai essaye d'ajouter l'option DT_END_ELLIPSIS a ton code, mais ca n'a pas marche.
    ::
    Chez moi non plus !!!!

    Tant pis...
    Bidouilleuse Delphi

  17. #17
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Non, sans, rire, DT_WORDBREAK et DT_END_ELLIPSIS n'ont pas l'air de faire bon ménage...
    Bidouilleuse Delphi

  18. #18
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 245
    Points : 154
    Points
    154
    Par défaut
    Donc la solution tombe a l'eau ?

  19. #19
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par Ben_Le_Cool
    Donc la solution tombe a l'eau ?
    En fait... non !
    Du coup, c'est mon code qui calcule les trois petits points, pas Windows...

    Voici le code :
    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
     
    type
      TAlignementVertical=(alVTop,alVCenter,alVBottom);
      TAlignementHorizontal=(alHLeft,alHCenter,alHRight);
      TJustification=(JustLeft,JustCenter,JustRight);
     
    //La valeur du paramètre AWidth détermine si on effectue unretour
    //à la ligne automatique ou non :
    //    - avec AWidth=0 => pas de WordWrap
    //    - avec AWidth<>0 => WorWrap sur la largeur donnée
    Function TextSize(Phrase : string; AWidth:integer; Police : TFont = nil) : TPoint;
    var
      DC: HDC;
      X: Integer;
      Rect: TRect;
      C : TBitmap;
      WordWrapParams:integer;
    begin
      C := TBitmap.create;
      if police <> nil then  C.canvas.Font := police;
     
        Rect.Left := 0;
        Rect.Top:=0;
        Rect.Right:=AWidth;
        Rect.Bottom:=0;
        DC := GetDC(0);
        C.Canvas.Handle := DC;
     
        WordWrapParams:=0;
        if AWidth<>0 then WordWrapParams:=DT_NOCLIP or DT_NOPREFIX or DT_WORDBREAK;
     
        DrawText(C.Canvas.Handle, PChar(Phrase), -1, Rect, WordWrapParams or (DT_EXPANDTABS or DT_CALCRECT));
        C.Canvas.Handle := 0;
        ReleaseDC(0, DC);
        result.X:=Rect.Right-Rect.Left;
        result.Y:=Rect.Bottom-Rect.Top;
        C.Free;
    end;
     
    //Notre procedure d'affichage de texte multiligne
    procedure DessineTexteMultiligne(AString: string; Ellipsis,WordWrap:boolean;ACanvas:TCanvas;ARect: TRect;
                           AlignementHorizontal:TAlignementHorizontal;
                           AlignementVertical:TAlignementVertical;
                           TextJustification:TJustification);
    var
      AHeight,AWidth:integer;
      Rect,oldClipRect:TRect;
      ATop,ALeft,H,W:Integer;
      AText:string;
      JustificationDuTexte:Integer;
      MyRgn:HRGN;
      APoint:TPoint;
    begin
      with ACanvas do
      begin
        Lock;
        AHeight:=ARect.Bottom-ARect.Top;
        AWidth:=ARect.Right-ARect.Left;
        //on calcule la taille du rectangle dans lequel va tenir le texte (sans WordWrap)
        APoint:=TextSize(AString,0,ACanvas.Font);
        W:=APoint.X;
        H:=APoint.Y;
     
        //on calcule la position (Haut,Gauche) du rectangle dans lequel va tenir le texte
        //en fonction de l'alignement horizontal et vertical choisis
        ATop:=ARect.Top;
        ALeft:=ARect.Left;
     
        If WordWrap then //Si on veut un "WordWrap" (retour à la ligne automatique)
          if W>(ARect.Right-ARect.Left) then //et que le texte dépasse du rectangle de destination
          begin //alors...
            W:=AWidth; //on fixe la largeur du texte
            AText:=AString;
            H:=TextSize(AText,W,ACanvas.Font).y; //on recalcule la hauteur du texte
            if Ellipsis then
            begin
               while (H>AHeight) do
               begin
                 AText:=Copy(AText,1,Length(AText)-1);
                 H:=TextSize(AText+'...',W,ACanvas.Font).y;
               end;
               AText:=AText+'...';
            end;
          end;
     
        case AlignementVertical of
          alVBottom : ATop:=ARect.Bottom-H;
          alVCenter : ATop:=ARect.Top+((AHeight-H) div 2);
          alVTop    : ATop:=ARect.Top;
        end;
     
        case AlignementHorizontal of
          alHLeft  : ALeft:=ARect.Left;
          alHCenter: ALeft:=ARect.Left+(AWidth-W) div 2;
          alHRight : ALeft:=ARect.Right-W;
        end;
     
        //Fin du calcul du rectangle, on met le resultat dans Rect
        Rect:=Bounds(ALeft,ATop,W,H);
     
        //On rempli le rectangle de la zone sinon on voit le texte que delphi à dessiné
        FillRect(ARect);
     
        //On détermine les paramètres de justification à passer à Windows
        case TextJustification of
          JustLeft  : JustificationDuTexte:=DT_LEFT;
          JustCenter: JustificationDuTexte:=DT_CENTER;
          JustRight : JustificationDuTexte:=DT_RIGHT;
        end;
     
        //Si le texte est plus grand que notre zone, on prend cette précaution (Clipping)
        with ARect do MyRgn :=CreateRectRgn(Left,Top,Right,Bottom);
        SelectClipRgn(Handle,MyRgn);
     
        //On dessine le texte
        DrawText(Handle,PChar(AText),-1,Rect,JustificationDuTexte or DT_NOCLIP or DT_NOPREFIX or DT_WORDBREAK );
     
        //On a plus besoin de la zone de clipping
        SelectClipRgn(Handle,0);
        DeleteObject(MyRgn);
        Unlock;
      end;
    end;
    Il y a un nouveau paramètre dans ma fonction DessinneTexteMultiligne qui active ou non le cacul des "trois ppetits points" : Ellipsis.
    Ce paramètre n'est pris en compte que si WordWrap est mis à true...
    Bidouilleuse Delphi

  20. #20
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 245
    Points : 154
    Points
    154
    Par défaut
    Ton code fonctionne presque parfaitement, juste une petite erreur: Si le texte est court (pas besoin de formattage), ta variable AText ne sera jamais assignee, donc on aura un vide en retour.

    Voici la portion du code corrigee:
    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
     
    procedure DessineTexteMultiligne(AString: string; Ellipsis,WordWrap:boolean;ACanvas:TCanvas;ARect: TRect;
                           AlignementHorizontal:TAlignementHorizontal;
                           AlignementVertical:TAlignementVertical;
                           TextJustification:TJustification);
    var
      AHeight,AWidth:integer;
      Rect,oldClipRect:TRect;
      ATop,ALeft,H,W:Integer;
      AText:string;
      JustificationDuTexte:Integer;
      MyRgn:HRGN;
      APoint:TPoint;
    begin
      with ACanvas do
      begin
        Lock;
        AHeight:=ARect.Bottom-ARect.Top;
        AWidth:=ARect.Right-ARect.Left;
        //on calcule la taille du rectangle dans lequel va tenir le texte (sans WordWrap)
        APoint:=TextSize(AString,0,ACanvas.Font);
        W:=APoint.X;
        H:=APoint.Y;
     
        //on calcule la position (Haut,Gauche) du rectangle dans lequel va tenir le texte
        //en fonction de l'alignement horizontal et vertical choisis
        ATop:=ARect.Top;
        ALeft:=ARect.Left;
     
        AText:=AString;  // Nouvel emplacement de l'assignement de AText
        If WordWrap then //Si on veut un "WordWrap" (retour à la ligne automatique)
          if W>(ARect.Right-ARect.Left) then //et que le texte dépasse du rectangle de destination
          begin //alors...
            W:=AWidth; //on fixe la largeur du texte
            H:=TextSize(AText,W,ACanvas.Font).y; //on recalcule la hauteur du texte
            if Ellipsis then 
            begin 
               while (H>AHeight) do 
               begin 
                 AText:=Copy(AText,1,Length(AText)-1); 
                 H:=TextSize(AText+'...',W,ACanvas.Font).y;
               end; 
               AText:=AText+'...'; 
            end; 
          end; 
     
        case AlignementVertical of
          alVBottom : ATop:=ARect.Bottom-H; 
          alVCenter : ATop:=ARect.Top+((AHeight-H) div 2); 
          alVTop    : ATop:=ARect.Top; 
        end; 
     
        case AlignementHorizontal of
          alHLeft  : ALeft:=ARect.Left; 
          alHCenter: ALeft:=ARect.Left+(AWidth-W) div 2; 
          alHRight : ALeft:=ARect.Right-W; 
        end; 
     
        //Fin du calcul du rectangle, on met le resultat dans Rect
        Rect:=Bounds(ALeft,ATop,W,H); 
     
        //On rempli le rectangle de la zone sinon on voit le texte que delphi à dessiné
        FillRect(ARect);
     
        //On détermine les paramètres de justification à passer à Windows
        case TextJustification of 
          JustLeft  : JustificationDuTexte:=DT_LEFT; 
          JustCenter: JustificationDuTexte:=DT_CENTER; 
          JustRight : JustificationDuTexte:=DT_RIGHT; 
        end; 
     
        //Si le texte est plus grand que notre zone, on prend cette précaution (Clipping) 
        with ARect do MyRgn :=CreateRectRgn(Left,Top,Right,Bottom); 
        SelectClipRgn(Handle,MyRgn); 
     
        //On dessine le texte 
        DrawText(Handle,PChar(AText),-1,Rect,JustificationDuTexte or DT_NOCLIP or DT_NOPREFIX or DT_WORDBREAK );
     
        //On a plus besoin de la zone de clipping 
        SelectClipRgn(Handle,0); 
        DeleteObject(MyRgn); 
        Unlock; 
      end;
    end;

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Centrer verticalement Image+texte dans un <td>
    Par lolymeupy dans le forum Mise en page CSS
    Réponses: 12
    Dernier message: 02/09/2011, 10h28
  2. Problème pour centrer verticalement le texte dans un menu
    Par Greg12345 dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 26/05/2010, 19h43
  3. [CR9] Centrer verticalement le texte
    Par CDRIK dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 22/05/2009, 19h33
  4. [SWT] Centrer verticalement le texte dans un label avec SWT
    Par Poulpynette dans le forum SWT/JFace
    Réponses: 11
    Dernier message: 14/03/2008, 11h12
  5. Centrer verticalement du text dans un dbgrid
    Par pierrot67 dans le forum Bases de données
    Réponses: 1
    Dernier message: 17/06/2006, 13h05

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