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 !
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.