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

3/5 (8 avis)

Vue 11 865 fois - Téléchargée 1 064 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
cs_Zeroc00l Messages postés 367 Date d'inscription lundi 1 avril 2002 Statut Membre Dernière intervention 11 février 2010
16 déc. 2006 à 14:35
Ouais ... il y a 4 fois cette ligne de code dans le code source.
Je suis sous "Windows XP - SP2"
Et ca clignote tjrs ! :-/
cs_Laurent1313 Messages postés 24 Date d'inscription jeudi 19 juin 2003 Statut Membre Dernière intervention 15 décembre 2008
14 déc. 2006 à 12:51
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.
cs_Zeroc00l Messages postés 367 Date d'inscription lundi 1 avril 2002 Statut Membre Dernière intervention 11 février 2010
25 juil. 2006 à 05:26
Y'a un moyen d'empecher la selection pour les url ?
Elle se voit pendant une fraction de seconde je trouve ca porcasse ...
cs_bloom1 Messages postés 328 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 8 mars 2007
13 août 2005 à 23:50
ah :S
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
13 août 2005 à 23:49
Delphi s'achète chez Borland et tout revendeur agréé.
Merci de ne pas insister avec ce genre de demandes sur CS.

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.