RICHTEXTBOX D'EDITION C# AVEC COLORISATION SYTAXIQUE

Signaler
Messages postés
18
Date d'inscription
jeudi 7 juin 2001
Statut
Membre
Dernière intervention
19 avril 2010
-
Messages postés
15940
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 mai 2021
-
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/51632-richtextbox-d-edition-c-avec-colorisation-sytaxique

Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
J'ai amélioré la chose, en supprimant le scintillement, et en relookant un peu le code (exit UpdateColor...)
Je n'avais pas besoin des Keywords, a vous de les remettre...

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using tom;

namespace TextDefinitionWindow {
class RichTextBox : System.Windows.Forms.RichTextBox {
private struct ColorItem {
public Regex Regex;
public Color Forecolor;

public ColorItem(String vsPattern, RegexOptions veRegexOptions, Color veForeColor) {
Regex = new Regex(vsPattern, veRegexOptions | RegexOptions.Compiled);
Forecolor = veForeColor;
}
}

private Thread th = null;
private bool InternalChange = false;
private List<ColorItem> ColorItems = new List<ColorItem>();

public RichTextBox() {
}

#region WIN32
[DllImport("User32.dll")]
private static extern int SendMessage(IntPtr hWnd, int message, IntPtr wParam, out IntPtr lParam);

private const int EM_GETOLEINTERFACE = WM_USER + 60;
private const int WM_USER = 0x0400;
#endregion

#region TOM OBJECT MODEL
private ITextDocument _oTextDocument = null;
private ITextDocument TextDocument {
get {
if (_oTextDocument == null)
_oTextDocument = Create();
return _oTextDocument;
}
set {
if (_oTextDocument != null)
Marshal.ReleaseComObject(_oTextDocument);
_oTextDocument = value;
}
}

private ITextDocument Create() {
IntPtr oRichEditOle = IntPtr.Zero;
if (SendMessage(base.Handle, EM_GETOLEINTERFACE, IntPtr.Zero, out oRichEditOle) == 0)
throw new System.ComponentModel.Win32Exception();
try {
return (ITextDocument)Marshal.GetTypedObjectForIUnknown(oRichEditOle, typeof(ITextDocument));
}
finally {
Marshal.Release(oRichEditOle);
}
}

private delegate void SetForecolorDelegate(int vnStart, int vnLength, Color veForecolor);
private void SetForecolor(int vnStart, int vnLength, Color veForecolor) {
if (this.InvokeRequired)
this.Invoke(new SetForecolorDelegate(SetForecolor), new Object[] { vnStart, vnLength, veForecolor });
else {
ITextRange Range = TextDocument.Range(vnStart, vnStart + vnLength);
int ForeColor = ColorTranslator.ToOle(veForecolor);
// On n'appelle le coloriage que si nécessaire
if (Range.Font.ForeColor != ForeColor) {
InternalChange = true;
//TextDocument.Freeze();
Range.Font.ForeColor = ForeColor;
//TextDocument.Unfreeze();
InternalChange = false;
}
}
}
#endregion

public void SyntaxColor(object data) {
String Text = data as String;

// Permettra de mettre en noir le texte neutre.
List ColoredItems = new List();
ColoredItems.Add(0);
ColoredItems.Add(Text.Length);

foreach(ColorItem Item in ColorItems)
foreach (Match Match in Item.Regex.Matches(Text)) {
ColoredItems.Add(Match.Index);
ColoredItems.Add(Match.Index + Match.Length);
// On supprime le texte de l'item de la variable Texte.
Text = Text.Substring(0, Match.Index) + new String(' ', Match.Length) + Text.Substring(Match.Index + Match.Length);
SetForecolor(Match.Index, Match.Length, Item.Forecolor);
}

// On colorie en noir le texte restant
ColoredItems.Sort();
int[] TextIndexes = ColoredItems.ToArray();
for (int i = 0; i + 1 < TextIndexes.Length; i += 2)
SetForecolor(TextIndexes[i], TextIndexes[i + 1] - TextIndexes[i], Color.Black);
}

protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);

// J'ai plus ou moins laissé les Regexp, il faudrait les blinder un peu...
/* color commentaire // */
ColorItems.Add(new ColorItem("//[^\r\n]*", RegexOptions.Singleline, Color.Green));
/* color commentaire multiligne */
ColorItems.Add(new ColorItem("/\\*[\\s\\S]\\*/", RegexOptions.Multiline, Color.Green));
/* color string */
ColorItems.Add(new ColorItem(""[^\\\\]"", RegexOptions.Singleline, Color.Red));
SyntaxColor(base.Text);
}

protected override void OnTextChanged(EventArgs e) {
// Ne se déclenche pas pendant notre coloriage
if (!InternalChange) {
base.OnTextChanged(e);
if (th != null && th.IsAlive) {
// Plutot que de sortir (notre appel etant justifié)
// on annule le thread de coloriage en cours
th.Abort();
// On s'assure de l'efficacité de notre dernier appel
while (th.ThreadState != ThreadState.Stopped)
Thread.Sleep(1);
}
th = new Thread(new ParameterizedThreadStart(SyntaxColor));
th.IsBackground = true;
th.Start(Text);
}
}
}
}
Messages postés
8
Date d'inscription
jeudi 26 juillet 2007
Statut
Membre
Dernière intervention
11 mai 2010

autant pour moi je ne l'avais pas vu. Merci
Messages postés
380
Date d'inscription
samedi 22 janvier 2005
Statut
Membre
Dernière intervention
13 août 2011
7
salut il faut ajouter la reference COM tom
Afficher les 9 commentaires