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 :

StringGrid, multiligne et word wrap


Sujet :

C++Builder

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 58
    Points : 86
    Points
    86
    Par défaut [Résolu] StringGrid, multiligne et word wrap
    Hello!

    Bon, j'ai déjà vu les posts traitant du mutiligne dans les tring grid, mais comme cela ne correspond pas tout a fait à ce que je souhaite faire, je me permet de faire un nouveau thread.

    Mon application remplit une StringGrid 30*3000 à partir d'un fichier .csv généré avec Excel. L'import de texte se passe tout bien et j'utilise les deux bouts de code suivants pour adapterla taille de mes cellules à ce qu'il y a dedans:

    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
    void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
          int ARow, TRect &Rect, TGridDrawState State)
    {
            //Texte sur plsr lignes:
            AnsiString s = StringGrid1->Cells[ACol][ARow];
            div_t nbl;
     
            nbl = div (s.Length(),30);
     
            int hauteur = (Rect.Top - Rect.Bottom)/(nbl.quot + 1);
            TRect R = Rect;
     
            for(int i = 0; i<=nbl.quot; i++)
            {
                    AnsiString t = s.SubString(1 + 30*i, 30);
                    R.Top = Rect.Top - (i*hauteur);
                    R.Bottom = R.Top - hauteur;
                    StringGrid1->Canvas->TextRect(R, R.Left, (R.Top + R.Bottom - StringGrid1->Canvas->TextHeight(t)) / 2, t);
            }
    }
    et, dans le constructeur de la fiche:
    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
    div_t nbl;
                    int tmplig = 0, final = 0;
                    for(int i = 0; i < StringGrid1->RowCount; i++)
                    {
                            final=25;
                            for(int j = 0; j < StringGrid1->ColCount; j++)
                            {
                                    nbl = div(StringGrid1->Cells[j][i].Length(),30);
                                    if(nbl.quot >= 1)
                                    {
                                            tmplig=StringGrid1->Canvas->TextHeight(StringGrid1->Cells[j][i])*(nbl.quot+1);
                                            if(final < tmplig)
                                                    final = tmplig;
                                    }
                                    StringGrid1->RowHeights[i]=final;
     
                            }
                    }
    et la meme chose pour la largeur.

    Ca marche tout bien, mais le problème c'est que je coupe mes chaines lorsqu'elles dépassent un certain nombre de caractères (ici 30) et c'est un peu violent comme façon de faire... d'autant que ca ne tient pas compte de la largeur réelle des caractères donc des fois, ma chaine est coupée alors qu'il y aurai eu la place de terminer sur la meme ligne...

    Est-ce que qqun s'est déjà penché sur la question, et à trouver un moyen de faire du word wrap dans les cellules de la string grid, avec un traitement assez rapide (j'ai des solutions qui marchent plus ou moins, mais comme j'ai 3000 lignes, le traitement est très long :/ )

    Merci d'avance

    Arnaud
    Tuning and optimization are not a fix to a bad design. A good design is a fix to a bad design.

  2. #2
    Membre habitué
    Avatar de Alacazam
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 88
    Points : 167
    Points
    167
    Par défaut
    Salut,

    Si j'ai compris ton problème, la solution est dans mon Post précédent sur le même sujet ...

    Il faut utiliser StringGrid->Canvas->TextWidth plutôt que Length() (comme dans ton code) ... qui ne tient pas compte (comme tu l'as fait remarquer) de la largeur des caractères.

    Le problème est évidemment le suivant :
    où couper le texte ?

    Peut-être qu'en utilisant un TLabel invisible, et en entrant d'abord le texte dedans (en utilisant donc WordWrap), on pourrait trouver où la coupure est faite par défaut et s'en servir comme dans mon exemple précédent ??

    J'espère avoir été à peu près clair

    Bonne Chance
    Mathieu
    Développeur confirmé C++, Java, Python, JS.

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 58
    Points : 86
    Points
    86
    Par défaut
    Ok... je vais essayer la méthode TLablel invisible ca me paraît pas mal... merci (o:

    Arnaud
    Tuning and optimization are not a fix to a bad design. A good design is a fix to a bad design.

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 58
    Points : 86
    Points
    86
    Par défaut
    Des fois que qqun aies un jour le même problème et tombe sur ce post...

    La méthode de passer par un composant invisible gérant le word wrap marche très bien. Je suis passé par un TMemo plutot qu'un TLabel pour récupérer les lignes de manière très simple avec la propriété lines->strings[i] du TMemo.

    Merci pour l'idée Alacazam (o:
    Tuning and optimization are not a fix to a bad design. A good design is a fix to a bad design.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 44
    Points : 26
    Points
    26
    Par défaut WordWrap dans un StringGrid
    hello

    Dajon a ecrit:
    Des fois que qqun aies un jour le même problème et tombe sur ce post...

    La méthode de passer par un composant invisible gérant le word wrap marche très bien. Je suis passé par un TMemo plutot qu'un TLabel pour récupérer les lignes de manière très simple avec la propriété lines->strings[i] du TMemo.
    J'utilise cette methode mais ne parvient pas a écrire sur plusieurs lignes dans mes cellules de StrinGrid

    faut-il utiliser le "\r\n" entre chaque ligne [i] du memo
    et si oui, quelle est la synthaxe (guillemts, apostrophe??)

    merci

  6. #6
    Membre habitué
    Avatar de Alacazam
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 88
    Points : 167
    Points
    167
    Par défaut Re: WordWrap dans un StringGrid
    Bonjour,

    Citation Envoyé par titicurio
    faut-il utiliser le "\r\n" entre chaque ligne [i] du memo
    et si oui, quelle est la synthaxe (guillemts, apostrophe??)
    Non, il te faut écrire sur le Canvas de ta grille.

    Dans l'événement OnDrawCell :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    StringGrid1->Canvas->Brush->Color = clWhite;
    StringGrid1->Canvas->FillRect(Rect);
    Pour effacer la case, puis tu écris à l'intérieur avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    StringGrid1->Canvas->TextRect
    Bonne Continuation,
    Mathieu
    Développeur confirmé C++, Java, Python, JS.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 44
    Points : 26
    Points
    26
    Par défaut
    En fait je ne vois pas comment utiliser le Memo dans le code du canva de mon StringGrid

    [ Modération, Alacazam : Sujets regroupés ]

  8. #8
    Membre habitué
    Avatar de Alacazam
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 88
    Points : 167
    Points
    167
    Par défaut
    Bonjour,

    Citation Envoyé par titicurio
    En fait je ne vois pas comment utiliser le Memo dans le code du canva de mon StringGrid
    Si tu as bien lu le lien en question, tu verras que le TMemo sert seulement à te diviser ton texte en morceaux de phrases, selon sa largeur !

    (J'avais à l'époque proposé un TLabel qui possédait le WordWrap, mais le TMemo est mieux, car on accède aux lignes directement par Memo1->Lines).

    Voilà, ça devrait aller :
    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
    void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, long Col, long Row,
    	TRect &Rect, TGridDrawState State)
    {
    TMemo *Memo = new TMemo(this);
    Memo->Visible = false;
    Memo->Parent = Form1;
    Memo->Lines->Text = StringGrid1->Cells[Col][Row];
    Memo->Width = StringGrid1->ColWidths[Col];
    int Cell_Height = Rect.Bottom - Rect.Top, Ligne_Num = Memo->Lines->Count;
     
    for (int i = 0 ; i < Ligne_Num ; i++) {
    	TRect R = Rect;
    	AnsiString Text_i = Memo->Lines->Strings[i];
    	R.Top = Rect.Top + i * Cell_Height / Ligne_Num;
        R.Bottom = Rect.Top + (i + 1) * Cell_Height / Ligne_Num;
    	StringGrid1->Canvas->TextRect(R, (R.Right + R.Left - StringGrid1->Canvas->TextWidth(Text_i)) / 2, (R.Top + R.Bottom - StringGrid1->Canvas->TextHeight(Text_i)) / 2, Text_i);
    	}
    delete Memo;
    }
    Bonne Continuation,
    Mathieu
    Développeur confirmé C++, Java, Python, JS.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Texte] Word Wrap
    Par prgasp77 dans le forum Contribuez
    Réponses: 0
    Dernier message: 14/11/2008, 16h42
  2. [C] comme faire WordBreak (word wrap) en EditControl?
    Par pc2-bresil dans le forum Windows
    Réponses: 2
    Dernier message: 15/12/2007, 01h08
  3. Réponses: 0
    Dernier message: 26/11/2007, 12h26
  4. Word-wrap firefox et IE
    Par 20-a-box dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 12/12/2006, 15h49

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