Richedit : mettre à jour le texte en couleur en temps réel.

Soyez le premier à donner votre avis sur cette source.

Vue 11 358 fois - Téléchargée 1 019 fois

Description

Suite et fin des tutos sur les RichEdit. Ici il s'agit de mettre à jour les attributs du texte pendant que l'utilisateur tape quelque chose. Pour faire ça on pourrait bien sûr appeler la fonction HighlightURL mais - comme elle fait un traitement sur tout le texte - ce serait bcp trop lent (le texte "clignoterait" pendant la frappe ce qui n'est pas très agréable ^^).

Au lieu de ça, on va donc mettre à jour _uniquement_ le mot sous le curseur sans toucher au reste du texte. Si le mot est une URL on le met en bleu souligné sinon en noir. Cela peut se faire relativement rapidement, en tout cas assez rapidement pour que l'utilisateur ne voit pas de différence (pas de clignotements) et ce même sur de gros textes.

Comme d'habitude, le code peut être adapté ou étendu pour gérer autre chose que des URL ^^

Source / Exemple :


function isValidChar(const c : char) : boolean;
const validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$-_.+!*''(),{}|\^~[]`<>#%|<>;/?:@&=';
begin
  result := Pos(c, validChars) <> 0;
end;

// Met à jour le mot sous le curseur sans considérer le reste du texte.
procedure UpdateWordUnderCursor(const RichEdit : TRichEdit);
var
  iWordStart, iWordEnd,
  iCharIndex, iLineIndex, iCharOffset: Integer;
  theWord : string;
  saveSelStart : integer;
begin
  if RichEdit.Cursor <> crNone then RichEdit.Cursor := crNone;

  iCharIndex := RichEdit.SelStart;

  if iCharIndex >= 0 then begin
    // Récupère l'index de la ligne
    iLineIndex := RichEdit.Perform(EM_EXLINEFROMCHAR, 0, LPARAM(iCharIndex));
    // Récupère la position du caractère par rapport au début de la ligne
    iCharOffset := iCharIndex - RichEdit.Perform(Messages.EM_LINEINDEX, WPARAM(iLineIndex), 0);

   // Récupère le mot sous le curseur
    if length(RichEdit.Lines[iLineIndex]) > 0 then begin
      // La partie gauche du mot
      iWordStart := iCharOffset;
      iCharIndex := iCharIndex;
      while iWordStart > 0 do begin
        if isValidChar(RichEdit.Lines[iLineIndex][iWordStart]) then begin
          iWordStart := iWordStart - 1;
          iCharIndex := iCharIndex - 1;
        end else begin
          break;
        end;
      end;

      // La partie droite
      iWordEnd := iCharOffset + 1;
      while iWordEnd < length(RichEdit.Lines[iLineIndex]) do begin
        if isValidChar(RichEdit.Lines[iLineIndex][iWordEnd]) then
          iWordEnd := iWordEnd + 1
        else
          break;
      end;

      theWord := Copy(RichEdit.Lines[iLineIndex], iWordStart + 1, iWordEnd - iWordStart);
    end;

    // On sauvegarde la position actuelle du curseur
    SaveSelStart := RichEdit.SelStart;
    // On cache le marqueur de sélection
    RichEdit.Perform(Messages.WM_USER + 63, WPARAM(TRUE), LPARAM(FALSE));
    // Positionne le curseur au début du mot
    RichEdit.SelStart := iCharIndex;
    // Etend la sélection pour sélectionner tout le mot
    RichEdit.SelLength := length(theWord);
    // Si le mot est une URL
    if pos('http://', theWord) = 1 then begin // On la met en bleu souligné
      RichEdit.SelAttributes.Color := clBlue;
      RichEdit.SelAttributes.Style := [fsUnderline];
    end else begin // sinon on restore la couleur par défaut (ici noir)
      RichEdit.SelAttributes.Color := clBlack;
      RichEdit.SelAttributes.Style := [];
    end;
    // On remet le curseur à sa position initiale
    RichEdit.SelStart := SaveSelStart;
    // On rend visible à nouveau le curseur
    RichEdit.Perform(Messages.WM_USER + 63, WPARAM(FALSE), LPARAM(FALSE));
  end;
end;

Conclusion :


Voilà, fin des tutos pour une manipulation "avancée" des RichEdit :) Je suppose qu'il existe déjà des composants qui gèrent toutes ces fonctions mais c'est jamais inutile de savoir le faire soi-même avec des composants standards !

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
370
Date d'inscription
lundi 1 avril 2002
Statut
Membre
Dernière intervention
11 février 2010

Ouais ... il y a 4 fois cette ligne de code dans le code source.
Je suis sous "Windows XP - SP2"
Et ca clignote tjrs ! :-/
Messages postés
24
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
15 décembre 2008

As-tu cette ligne dans ton code:

# // On cache le marqueur de sélection
# RichEdit.Perform(Messages.WM_USER + 63, WPARAM(TRUE), LPARAM(FALSE));

Normalement cette partie-la est censee masquer la selection.
Messages postés
370
Date d'inscription
lundi 1 avril 2002
Statut
Membre
Dernière intervention
11 février 2010

Y'a un moyen d'empecher la selection pour les url ?
Elle se voit pendant une fraction de seconde je trouve ca porcasse ...
Messages postés
328
Date d'inscription
jeudi 26 août 2004
Statut
Membre
Dernière intervention
8 mars 2007

ah :S
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
21
Delphi s'achète chez Borland et tout revendeur agréé.
Merci de ne pas insister avec ce genre de demandes sur CS.
Afficher les 8 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.