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

Langage Delphi Discussion :

Rechercher et marquer du texte dans un TRichedit


Sujet :

Langage Delphi

  1. #1
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 169
    Points
    169
    Par défaut Rechercher et marquer du texte dans un TRichedit
    Bonjour à tous !

    Voici ma procédure qui permet une simple colorisation de mot clé dans un TRichEdit, le souci c'est ! que j'aimerai faire le traitement de la colorisation juste sur le texte sélectionné.

    Le souci dans cette procédure c'est quelle ne va pas jusqu'à fin de la sélection, elle s’arrête au première mots quelle trouve.

    Je pense que le problème viens bien du RichEdit.SelLength.

    Voici ma Procédure :
    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
    var
      KeyWord: Array [1 .. 5] of String = (
        'type',
        'var',
        'procedure',
        'begin',
        'end'
      );
     
    procedure HightLight(RichEdit: TRichEdit);
    var
      I, iPos, iNext: Integer;
    begin
      iNext := RichEdit.SelStart;
     
      for I := Low(KeyWord) to High(KeyWord) do
      begin
        iPos := RichEdit.FindText(KeyWord[I], iNext, RichEdit.SelLength,[stWholeWord]);
     
        while iPos <> -1 do
        begin
          iNext := iPos + Length(KeyWord[I]);
          RichEdit.SelStart := iPos;
          RichEdit.SelLength := Length(KeyWord[I]);
          RichEdit.SelAttributes.Color := clNavy;
          RichEdit.SelAttributes.Style := [fsbold];
          iPos := RichEdit.FindText(KeyWord[I], iNext, RichEdit.SelLength,[stWholeWord]);
        end;
      end;
    end;
    Merci.
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Je n'avais jamais travaillé avec le nouveau RichEdit (il n'y en a pas en FMX )

    Je propose une version un peu différente
    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
    var
      I, iPos: Integer;
     
    const KeyWord: Array [1 .. 5] of String = (
        'type',
        'var',
        'procedure',
        'begin',
        'end'
      );
     
    begin
    for I := Low(KeyWord) to High(KeyWord) do
     begin
     
      Ipos:=RichEdit1.FindText(keyword[i],0,Length(RichEdit1.Text),[stWholeWord]);
      repeat
          RichEdit1.SelStart := iPos;
          RichEdit1.SelLength := Length(keyword[i]);
          RichEdit1.SelAttributes.Color := clNavy;
          RichEdit1.SelAttributes.Style := [fsbold];
          Ipos:=RichEdit1.FindText(keyword[i],ipos+length(keyword[i]),Length(RichEdit1.Text),[stWholeWord]);
      until ipos=-1;
    end;
    nb. pour ce genre de chose, le composant SynEdit pourrait faire l'affaire
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    c'est assez logique puisque tu changes SelLength

    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
     
    var
      KeyWord: Array [1 .. 5] of String = (
        'type',
        'var',
        'procedure',
        'begin',
        'end'
      );
     
    procedure HightLight(RichEdit: TRichEdit);
    var
      I, iPos, iNext, iLen: Integer;
    begin
      iNext := RichEdit.SelStart;
      iLen := RichEdit.SelLength;
     
      for I := Low(KeyWord) to High(KeyWord) do
      begin
        iPos := RichEdit.FindText(KeyWord[I], iNext, iLen,[stWholeWord]);
     
        while iPos <> -1 do
        begin
          iNext := iPos + Length(KeyWord[I]);
          Dec(iLen, iNext - RichEdit.SelStart);
          RichEdit.SelStart := iPos;
          RichEdit.SelLength := Length(KeyWord[I]);
          RichEdit.SelAttributes.Color := clNavy;
          RichEdit.SelAttributes.Style := [fsbold];
          iPos := RichEdit.FindText(KeyWord[I], iNext, iLen,[stWholeWord]);
        end;
      end;
    end;
    je n'ai pas testé mais l'idée c'est de garder le SelLength original (iLen), et de le réduire au fur et à mesure qu'on avance dans la sélection originale
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 169
    Points
    169
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Bonjour,
    Je n'avais jamais travaillé avec le nouveau RichEdit (il n'y en a pas en FMX )

    Je propose une version un peu différente
    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
    var
      I, iPos: Integer;
     
    const KeyWord: Array [1 .. 5] of String = (
        'type',
        'var',
        'procedure',
        'begin',
        'end'
      );
     
    begin
    for I := Low(KeyWord) to High(KeyWord) do
     begin
     
      Ipos:=RichEdit1.FindText(keyword[i],0,Length(RichEdit1.Text),[stWholeWord]);
      repeat
          RichEdit1.SelStart := iPos;
          RichEdit1.SelLength := Length(keyword[i]);
          RichEdit1.SelAttributes.Color := clNavy;
          RichEdit1.SelAttributes.Style := [fsbold];
          Ipos:=RichEdit1.FindText(keyword[i],ipos+length(keyword[i]),Length(RichEdit1.Text),[stWholeWord]);
      until ipos=-1;
    end;
    nb. pour ce genre de chose, le composant SynEdit pourrait faire l'affaire
    Bonjour SergioMaster,

    pour ce genre de chose, le composant SynEdit pourrait faire l'affaire
    Oui effectivement, j'aime bien travailler avec les composants standard de la Vcl

    SelStart : détermine bien la position de départ.
    SelLength : Revoie bien la longueur de la sélection à parcourir.

    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
    procedure HightLight(RichEdit: TRichEdit);
    var
      I, iPos, iNext: Integer;
    begin
      iNext := RichEdit.SelStart;
     
      for I := Low(KeyWord) to High(KeyWord) do
      begin
     
        iPos := RichEdit.FindText(KeyWord[I], iNext, RichEdit.SelLength,[stWholeWord]);
     
        while iPos <> -1 do
        begin
          iNext := iPos + length(KeyWord[I]);
          RichEdit.SelStart := iPos;
          RichEdit.SelLength := length(KeyWord[I]);
          RichEdit.SelAttributes.Color := clNavy;
          RichEdit.SelAttributes.Style := [fsbold];
          iPos := RichEdit.FindText(KeyWord[I], iNext, RichEdit.SelLength,[stWholeWord]);
        end;
      end;
    end;
    Je n'arrive pas à capter ce qui cloche
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  5. #5
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 169
    Points
    169
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    c'est assez logique puisque tu changes SelLength

    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
     
    var
      KeyWord: Array [1 .. 5] of String = (
        'type',
        'var',
        'procedure',
        'begin',
        'end'
      );
     
    procedure HightLight(RichEdit: TRichEdit);
    var
      I, iPos, iNext, iLen: Integer;
    begin
      iNext := RichEdit.SelStart;
      iLen := RichEdit.SelLength;
     
      for I := Low(KeyWord) to High(KeyWord) do
      begin
        iPos := RichEdit.FindText(KeyWord[I], iNext, iLen,[stWholeWord]);
     
        while iPos <> -1 do
        begin
          iNext := iPos + Length(KeyWord[I]);
          Dec(iLen, iNext - RichEdit.SelStart);
          RichEdit.SelStart := iPos;
          RichEdit.SelLength := Length(KeyWord[I]);
          RichEdit.SelAttributes.Color := clNavy;
          RichEdit.SelAttributes.Style := [fsbold];
          iPos := RichEdit.FindText(KeyWord[I], iNext, iLen,[stWholeWord]);
        end;
      end;
    end;
    je n'ai pas testé mais l'idée c'est de garder le SelLength original (iLen), et de le réduire au fur et à mesure qu'on avance dans la sélection originale
    Bonjour Paul TOTH,

    Oui effectivement c'est beaucoup plus claire maintenant

    J'ai corrigé la procédure, on traite bien la sélection du RichEdit mes que dans le début de la sélection.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    type
      TForm1 = class(TForm)
        RichEdit1: TRichEdit;
        Btn_Colorier: TButton;
        procedure Btn_ColorierClick(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
    La colorisation se fait bien sur les mots "type, procedure" par contre le "end" n’est pas pris en conte.
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    oui, encore une fois c'est logique, tu as une boucle For sur les KeyWord, lors du premier passage iNext et iLen sont bons, mais lors de la seconde itération tu es arrivé à la fin de la sélection iLen = 0 et iNext pointe sur le dernier "type" mis en couleur.

    il faut donc conserver iNext et iLen avant la boucle et leur rendre leur valeur initiale à chaque itération.

    du coup, soit tu ajoutes 2 variables pour cela, soit tu crées une fonction de mise en couleur d'un KeyWord donné avec la position de départ et la longueur...j'aime bien cette deuxième solution qui rend les choses plus lisibles et évite d'avoir un code qui devient de plus en plus long.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure HighlightKeyword(RichEdit: TRichEdit; const Keyword: string; SelStart, SelLength: Integer);
    begin
      ...
    end;
    la fonction Highlight et alors une simple boucle sur le tableau Keyword qui appelle HighlightKeyword avec SelStart et SelLength qui ne bougent pas.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Ton erreur est dans la longueur du texte à rechercher (troisième argument de FindText)
    tu dois y indiquer la taille du texte en entier Length(RichEdit.Text)
    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
     
    procedure TForm7.Button1Click(Sender: TObject);
    var
      I, iPos: Integer;
    begin
    for I := Low(KeyWord) to High(KeyWord) do
     begin
      Ipos:=RichEdit1.FindText(keyword[i],0,Length(RichEdit1.Text),[stWholeWord]);
      repeat
          RichEdit1.SelStart := iPos;
          RichEdit1.SelLength := Length(keyword[i]);
          RichEdit1.SelAttributes.Color := clNavy;
          RichEdit1.SelAttributes.Style := [fsbold];
          Ipos:=RichEdit1.FindText(keyword[i],ipos+length(keyword[i]),Length(RichEdit1.Text),[stWholeWord]);
      until ipos=-1;
    end;
    end;
     
    procedure TForm7.Button2Click(Sender: TObject);
    begin
    HightLight(RichEdit1);
    end;
     
    procedure HightLight(RichEdit: TRichEdit);
    var
      I, iPos, iNext, L: Integer;
    begin
      L:=Length(RichEdit.Text);
      for I := Low(KeyWord) to High(KeyWord) do
      begin
        iNext :=0;
        iPos := RichEdit.FindText(KeyWord[I], iNext, L,[stWholeWord]);
        while iPos <> -1 do
        begin
          iNext := iPos + length(KeyWord[I]);
          RichEdit.SelStart := iPos;
          RichEdit.SelLength := length(KeyWord[I]);
          RichEdit.SelAttributes.Color := clNavy;
          RichEdit.SelAttributes.Style := [fsbold];
          iPos := RichEdit.FindText(KeyWord[I], iNext, L ,[stWholeWord]);
        end;
      end;
    end;
    Nom : Capture.PNG
Affichages : 204
Taille : 9,5 Ko

    résultat identique entre ma première proposition et le code "corrigé"
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  8. #8
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 169
    Points
    169
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    oui, encore une fois c'est logique, tu as une boucle For sur les KeyWord, lors du premier passage iNext et iLen sont bons, mais lors de la seconde itération tu es arrivé à la fin de la sélection iLen = 0 et iNext pointe sur le dernier "type" mis en couleur.

    il faut donc conserver iNext et iLen avant la boucle et leur rendre leur valeur initiale à chaque itération.

    du coup, soit tu ajoutes 2 variables pour cela, soit tu crées une fonction de mise en couleur d'un KeyWord donné avec la position de départ et la longueur...j'aime bien cette deuxième solution qui rend les choses plus lisibles et évite d'avoir un code qui devient de plus en plus long.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure HighlightKeyword(RichEdit: TRichEdit; const Keyword: string; SelStart, SelLength: Integer);
    begin
      ...
    end;
    la fonction Highlight et alors une simple boucle sur le tableau Keyword qui appelle HighlightKeyword avec SelStart et SelLength qui ne bougent pas.
    Cela devrai ressemblé a ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure HighlightKeyword(RichEdit: TRichEdit; Keyword: string; SelStart, SelLength: Integer);
    var
      iPos, iNext: Integer;
    begin // On rechercher la position du premier mots clé : Keyword.
        iPos := RichEdit.FindText(KeyWord, SelStart, SelLength,[stWholeWord]); // iPos = La position du premier mot clé trouvé.
     
        while iPos <> -1 do 
        begin
          iNext := iPos + Length(KeyWord); // On décale la position iNext de iPos + la longueur du mots clé.  
          RichEdit.SelAttributes.Color := clNavy;
          RichEdit.SelAttributes.Style := [fsbold];
          iPos := RichEdit.FindText(KeyWord, iNext, SelLength,[stWholeWord]); // On rechercher le suivent avec la nouvelle position iNext.
        end;
      end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure HightLight(RichEdit: TRichEdit);
    var
      I: Integer;
    begin
      for I := Low(KeyWord) to High(KeyWord) do
      begin
        HighlightKeyword(RichEdit, KeyWord[I], RichEdit.SelStart, RichEdit.SelLength);
      end;
    end;

    Nom : Capture.PNG
Affichages : 200
Taille : 7,8 Ko

    Il y a un début de quelque chose
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  9. #9
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    oui mais tu as reproduit le premier bug (la variable selLength doit être diminuée à chaque fois) tout en oubliant de modifier la sélection du RichEdit avant de définir la couleur du coup elle s'applique sur toute la sélection initiale.

    EDIT: j'en profite pour gagner un tour : ta boucle principale utilise la sélection courante du RichEdit, hors elle va être modifiée, il faut donc la conserver avant la boucle pour appeler la sous fonction avec toujours ces deux mêmes paramètres.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    procedure HightLight(RichEdit: TRichEdit);
    var
      SelStart, SelLength, I: Integer;
    begin
      SelStart := RichEdit.SelStart;
      SelLength := RichEdit.SelLength;
      for I := Low(KeyWord) to High(KeyWord) do
      begin
        HighlightKeyword(RichEdit, KeyWord[I], SelStart, SelLength);
      end;
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  10. #10
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Ton erreur est dans la longueur du texte à rechercher (troisième argument de FindText)
    tu dois y indiquer la taille du texte en entier Length(RichEdit.Text)
    Sergio, je ne suis pas d'accord avec ça, la requête et de pouvoir mettre en couleur la sélection courante du RichEdit, et non la totalité du texte.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  11. #11
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 169
    Points
    169
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    oui mais tu as reproduit le premier bug (la variable selLength doit être diminuée à chaque fois) tout en oubliant de modifier la sélection du RichEdit avant de définir la couleur du coup elle s'applique sur toute la sélection initiale.

    EDIT: j'en profite pour gagner un tour : ta boucle principale utilise la sélection courante du RichEdit, hors elle va être modifiée, il faut donc la conserver avant la boucle pour appeler la sous fonction avec toujours ces deux mêmes paramètres.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    procedure HightLight(RichEdit: TRichEdit);
    var
      SelStart, SelLength, I: Integer;
    begin
      SelStart := RichEdit.SelStart;
      SelLength := RichEdit.SelLength;
      for I := Low(KeyWord) to High(KeyWord) do
      begin
        HighlightKeyword(RichEdit, KeyWord[I], SelStart, SelLength);
      end;
    end;
    Voici la correction des procédures "HighlightKeyword" & "HightLight" cela a l’air de fonctionné

    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
    procedure HighlightKeyword(RichEdit: TRichEdit; Keyword: string; SelStart, SelLength: Integer);
    var
      iPos, iNext: Integer;
    begin
        iPos := RichEdit.FindText(KeyWord, SelStart, SelLength,[stWholeWord]);
     
        while iPos <> -1 do
        begin
          iNext := iPos + Length(KeyWord);
          Dec(SelLength, iNext - SelStart);
          RichEdit.SelStart := iPos;
          RichEdit.SelLength := Length(KeyWord);
          RichEdit.SelAttributes.Color := clNavy;
          RichEdit.SelAttributes.Style := [fsbold];
          iPos := RichEdit.FindText(KeyWord, iNext, SelLength,[stWholeWord]);
        end;
      end;
     
    procedure HightLight(RichEdit: TRichEdit);
    var
      SelStart, SelLength, I: Integer;
    begin
      SelStart := RichEdit.SelStart;
      SelLength := RichEdit.SelLength;
     
      for I := Low(KeyWord) to High(KeyWord) do
      begin
        HighlightKeyword(RichEdit, KeyWord[I], SelStart, SelLength);
      end;
    end;
    Nom : Capture.PNG
Affichages : 198
Taille : 28,7 Ko
    Nom : Capture1.PNG
Affichages : 198
Taille : 27,9 Ko
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  12. #12
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    oui, après il faut savoir que ce genre de mise en couleur a ses limites...par exemple, le mot "type" dans un commentaire sera mis en couleur, tout comme le mot type dans une chaîne de caractères.

    même Delphi a ses limites (alors qu'il utilise un procédé complètement différent), dans l'exemple ci-dessous

    Nom : Sans titre.png
Affichages : 193
Taille : 9,5 Ko

    les mots Message et Index n'ont pas lieu d'être en gras.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  13. #13
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 169
    Points
    169
    Par défaut
    Merci Paul TOTH & SergioMaster pour votre aide
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  14. #14
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Perso j'aurais fait ça par expressions régulières
    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
    uses System.RegularExpressions;
     
    procedure HightLight(RichEdit: TRichEdit);
    const
      Comments      = '//.*?(\R|$)|\{[^\$].*?\}|\(\*.*?\*\)';
      Directives    = '\{\$.*?\}';
      strings       = '''.*?(?<!'')''(?!'')';
      ReservedWords = '\b(?>type|var|procedure|begin|end)\b';
      Numbers       = '(?<=^|\s|\W)#?\d[0-9\.]*';
     
    var
      Start :integer;
      Text  :string;
     
      //--------------------------------------------------------------------------------------------------
      procedure DoHighlight(const aPattern :string; aColor :TColor; aStyle :TFontStyles = []);
      begin
        const Matches = TRegEx.Matches(Text, aPattern, [roSingleline, roIgnoreCase, roExplicitCapture]);
     
        for var Match in Matches do
        begin
          RichEdit.SelStart := Start +Match.Index -1;
     
          // 1ère position protégée ?
          RichEdit.SelLength := 1;
          if RichEdit.SelAttributes.Protected then Continue;
     
          // Non, déprotège toute la sélection
          RichEdit.SelLength               := Match.Length;
          RichEdit.SelAttributes.Protected := FALSE;
     
          RichEdit.SelAttributes.Color     := aColor;
          RichEdit.SelAttributes.Style     := aStyle;
          RichEdit.SelAttributes.Protected := TRUE;
        end;
      end;
      //--------------------------------------------------------------------------------------------------
     
    begin
      Start := RichEdit.SelStart;
      Text  := RichEdit.SelText;
     
      DoHighlight(Comments, clGreen, [fsItalic]);
      DoHighlight(Directives, clTeal);
      DoHighlight(Strings, clBlue);
      DoHighlight(ReservedWords, clNavy, [fsBold]);
      DoHighlight(Numbers, clTeal);
    end;
     
    procedure TForm4.RichEdit1ProtectChange(Sender: TObject; StartPos, EndPos: Integer; var AllowChange: Boolean);
    begin
      AllowChange := TRUE;
    end;
     
    procedure TForm4.Button1Click(Sender: TObject);
    begin
      HightLight(RichEdit1);
    end;
    En jouant sur Protected les chaînes et commentaires sont correctement traités.

  15. #15
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    Sergio, je ne suis pas d'accord avec ça, la requête est de pouvoir mettre en couleur la sélection courante du RichEdit, et non la totalité du texte.
    Je n'avais fait que lire le titre donc pour moi, il s'agissait de tout le texte du TRichedit

    @Andnotor J'aime bien avec les expressions régulières, mais il me semble qu'il y a une limite de taille de texte à analyser ?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  16. #16
    Membre habitué Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 260
    Points : 169
    Points
    169
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Perso j'aurais fait ça par expressions régulières
    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
    uses System.RegularExpressions;
     
    procedure HightLight(RichEdit: TRichEdit);
    const
      Comments      = '//.*?(\R|$)|\{[^\$].*?\}|\(\*.*?\*\)';
      Directives    = '\{\$.*?\}';
      strings       = '''.*?(?<!'')''(?!'')';
      ReservedWords = '\b(?>type|var|procedure|begin|end)\b';
      Numbers       = '(?<=^|\s|\W)#?\d[0-9\.]*';
     
    var
      Start :integer;
      Text  :string;
     
      //--------------------------------------------------------------------------------------------------
      procedure DoHighlight(const aPattern :string; aColor :TColor; aStyle :TFontStyles = []);
      begin
        const Matches = TRegEx.Matches(Text, aPattern, [roSingleline, roIgnoreCase, roExplicitCapture]);
     
        for var Match in Matches do
        begin
          RichEdit.SelStart := Start +Match.Index -1;
     
          // 1ère position protégée ?
          RichEdit.SelLength := 1;
          if RichEdit.SelAttributes.Protected then Continue;
     
          // Non, déprotège toute la sélection
          RichEdit.SelLength               := Match.Length;
          RichEdit.SelAttributes.Protected := FALSE;
     
          RichEdit.SelAttributes.Color     := aColor;
          RichEdit.SelAttributes.Style     := aStyle;
          RichEdit.SelAttributes.Protected := TRUE;
        end;
      end;
      //--------------------------------------------------------------------------------------------------
     
    begin
      Start := RichEdit.SelStart;
      Text  := RichEdit.SelText;
     
      DoHighlight(Comments, clGreen, [fsItalic]);
      DoHighlight(Directives, clTeal);
      DoHighlight(Strings, clBlue);
      DoHighlight(ReservedWords, clNavy, [fsBold]);
      DoHighlight(Numbers, clTeal);
    end;
     
    procedure TForm4.RichEdit1ProtectChange(Sender: TObject; StartPos, EndPos: Integer; var AllowChange: Boolean);
    begin
      AllowChange := TRUE;
    end;
     
    procedure TForm4.Button1Click(Sender: TObject);
    begin
      HightLight(RichEdit1);
    end;
    En jouant sur Protected les chaînes et commentaires sont correctement traités.
    Bonjour Andnotor,

    Sous quelle plateforme as-tu développé cette procédure ?

    Nom : Capture.PNG
Affichages : 166
Taille : 140,2 Ko
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.

  17. #17
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 418
    Points : 5 816
    Points
    5 816
    Par défaut
    salut

    pour un gain de vitesse ne pas oublier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     RichEdit1.Lines.BeginUpdate;
     HightLight(RichEdit1);
     RichEdit1.Lines.EndUpdate;
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  18. #18
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Citation Envoyé par XeGregory Voir le message
    Sous quelle plateforme as-tu développé cette procédure ?
    D11.

    Les variables en ligne sont apparues en D10.3. Dans ton cas, passe par la déclaration habituelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var
      Matches :TMatchCollection;
      Match   :TMatch;
    begin
      Matches := TRegEx.Matches(Text, aPattern, [roIgnoreCase, roExplicitCapture]);
     
      for Match in Matches do ...

  19. #19
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 418
    Points : 5 816
    Points
    5 816
    Par défaut
    bonjour

    le probleme de cette methode c'est que tu vas vite etre ralentie avec de long texte
    il existe une autre methode qui permet de reconstruir le fichier rtf en une fois et le reinjecter a la fin


    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
     
    procedure TfChildWin2.UpdateSyntax(Editor : TRichEdit);
    ..
    begin
      if (Length(Editor.Text) > 0) then
      begin
        ...
        OutputStream := TMemoryStream.Create;
        try
          ....
          InputStream := TStringStream.Create(Editor.Text);
         ....
         try
           OutputStream := Process(ftrtf,TypeDocPas , InputStream); // ici tu fait le traitement sur ton fichier 
           OutputStream.seek(0, 0); //on se remet au debut du fichier
          ....  
            Editor.Lines.LoadFromStream(OutputStream); //on reinject le fichier rtf resultant
           ....  
          finally
            OutputStream.Free;
           ....  
          end;
        finally
          InputStream.Free;
        end;
        Editor.SelStart := Pos;
        Editor.OnChange := OnChange;
       ....  
      end;
    end;
    cela permet de differencier les données de l'affichage et d'etre polyvalent tu peux
    gerer plusieur type de documents en entree et en sortie
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  20. #20
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 685
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Citation Envoyé par anapurna Voir le message
    pour un gain de vitesse ne pas oublier
    Lines n'est pas modifié.

    Citation Envoyé par anapurna Voir le message
    il existe une autre methode qui permet de reconstruir le fichier rtf en une fois et le reinjecter a la fin
    Ce sera autrement plus compliqué d'insérer des balises rtf dans un texte.

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

Discussions similaires

  1. [XL-2007] recherche d'une valeur texte dans une plage de cellules
    Par blackstrange dans le forum Macros et VBA Excel
    Réponses: 23
    Dernier message: 13/07/2012, 16h26
  2. [XL-2007] Rechercher et afficher un text dans un fichier Word avec macro Excel
    Par ypelissier dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 26/03/2012, 16h51
  3. Réponses: 3
    Dernier message: 10/01/2012, 10h04
  4. Marquer des lignes dans un TRichEdit
    Par Speed41 dans le forum Débuter
    Réponses: 3
    Dernier message: 06/04/2011, 17h33
  5. Faire défiler du texte dans un TRichEdit
    Par engrobel dans le forum C++Builder
    Réponses: 7
    Dernier message: 04/11/2008, 20h33

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