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

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

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.