首先建立一个XML文件:csharp.xml
<?xml version="1.0" encoding="utf-8" ?> <definition name="C#" caseSensitive="true"> <word color="BLUE">private</word> <word color="BLUE">protected</word> <word color="BLUE">public</word> <word color="BLUE">namespace</word> <word color="BLUE">class</word> <word color="BLUE">for</word> <word color="BLUE">if</word> <word color="BLUE">else</word> <word color="BLUE">while</word> <word color="BLUE">switch</word> <word color="BLUE">case</word> <word color="BLUE">using</word> <word color="BLUE">get</word> <word color="BLUE">return</word> <word color="BLUE">null</word> <word color="BLUE">void</word> <word color="BLUE">int</word> <word color="BLUE">string</word> <word color="BLUE">float</word> <word color="BLUE">char</word> <word color="BLUE">this</word> <word color="BLUE">set</word> <word color="BLUE">new</word> <word color="BLUE">true</word> <word color="BLUE">false</word> <word color="BLUE">const</word> <word color="BLUE">static</word> <word color="BLUE">internal</word> <word color="BLUE">extends</word> <word color="BLUE">super</word> <word color="BLUE">import</word> <word color="BLUE">default</word> <word color="BLUE">break</word> <word color="BLUE">try</word> <word color="BLUE">catch</word> <word color="BLUE">finally</word> <word color="CadetBlue">Main</word> <word color="CadetBlue">WriteLine</word> <word color="CadetBlue">Console</word> <word color="CadetBlue">WriteLine</word> <word color="DarkOrange">;</word> <register>printf</register> </definition>
然后在VS中新建一工程,添加下面的这个类:
using System; using System.Xml; using System.IO; using System.Collections; using System.Reflection; using System.Drawing; namespace WindowsApplication1 { public class Parser { private XmlDocument xd=null; private ArrayList al=null; //对xml流解析后,会把每一个关键字字符串放入这个容器中 private bool caseSensitive=false; //记录当前语言大小写敏感否 private ArrayList cl=null;//对xml流解析后,把每一个C关键字颜色保留 internal Parser(SyntaxEditor.Languages language) //构造函数接受一个枚举变量 { Assembly asm = Assembly.GetExecutingAssembly(); string filename=""; switch(language) //取得xml文件名 { case SyntaxEditor.Languages.CSHARP: filename="csharp.xml"; break; case SyntaxEditor.Languages.JSHARP: filename="jsharp.xml"; break; case SyntaxEditor.Languages.SQL: filename="sql.xml"; break; case SyntaxEditor.Languages.VBSCRIPT: filename="vbscript.xml"; break; default: break; } StreamReader reader= new StreamReader(filename, System.Text.Encoding.UTF8 ); //下面的代码解析xml流 xd=new XmlDocument(); xd.Load(reader); al=new ArrayList(); cl=new ArrayList(); XmlElement root=xd.DocumentElement; XmlNodeList xnl=root.SelectNodes("/definition/word"); for(int i=0;i<xnl.Count;i++) { al.Add(xnl[i].ChildNodes[0].Value); //将关键子收集到al cl.Add(xnl[i].Attributes["color"].Value);//收集关键字的颜色 } //检测是否判断大小写 this.caseSensitive=bool.Parse(root.Attributes["caseSensitive"].Value); } public Color IsKeyWord(string word ) //判断字符串是否为关键字 { for(int i=0;i<al.Count;i++) { if(string.Compare(word,al[i].ToString(),!caseSensitive)==0) { string ColorTemp=(cl[i].ToString()!=string.Empty?cl[i].ToString():"Black"); Color c; try { c=Color.FromName(ColorTemp); } catch (Exception e) { c=Color.Black; } return c; } } return Color.Black; } } }
然后新建一用户控件继承RichTextBox
using System; using System.Drawing; using System.Runtime.InteropServices; using HWND = System.IntPtr; namespace WindowsFormsApplication2 { public partial class SyntaxEditor : System.Windows.Forms.RichTextBox { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.Container components = null; int line; private Parser parser; /// <summary> /// 必需的设计器变量。 /// </summary> //使用win32api:SendMessage来防止控件着色时的闪烁现象 [DllImport("user32")] private static extern int SendMessage(HWND hwnd, int wMsg, int wParam, IntPtr lParam); private const int WM_SETREDRAW = 0xB; public SyntaxEditor() { // 该调用是 Windows.Forms 窗体设计器所必需的。 InitializeComponent(); base.WordWrap = false; // TODO: 在 InitComponent 调用后添加任何初始化 } /// <summary> /// 清理所有正在使用的资源。 /// </summary> #region 组件设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器 /// 修改此方法的内容。 /// </summary> #endregion //重写基类的OnTextChanged方法。为了提高效率,程序是对当前文本插入点所在行进行扫描, //以空格为分割符,判断每个单词是否为关键字,并进行着色。 protected override void OnTextChanged(EventArgs e) { if (base.Text != "") { int selectStart = base.SelectionStart; line = base.GetLineFromCharIndex(selectStart); string lineStr = base.Lines[line]; int linestart = 0; for (int i = 0; i < line; i++) { linestart += base.Lines[i].Length + 1; } SendMessage(base.Handle, WM_SETREDRAW, 0, IntPtr.Zero); base.SelectionStart = linestart; base.SelectionLength = lineStr.Length; base.SelectionColor = Color.Black; base.SelectionStart = selectStart; base.SelectionLength = 0; //对一行字符串用空格或者.分开 string[] words = lineStr.Split(new char[] { ‘ ‘, ‘.‘, ‘\n‘, ‘(‘, ‘)‘, ‘}‘, ‘{‘, ‘"‘, ‘[‘, ‘]‘ }); parser = new Parser(this.language); for (int i = 0; i < words.Length; i++)//一个字符段一个字符段来判断 { //判断是否是程序保留字 是的话高亮显示 if (parser.IsKeyWord(words[i]) != Color.Empty) { int length = 0; for (int j = 0; j < i; j++) { length += words[j].Length; } length += i; int index = lineStr.IndexOf(words[i], length); base.SelectionStart = linestart + index; base.SelectionLength = words[i].Length; //base.SelectionFont base.SelectionColor = parser.IsKeyWord(words[i]); base.SelectionStart = selectStart; base.SelectionLength = 0; base.SelectionColor = Color.Black; } } SendMessage(base.Handle, WM_SETREDRAW, 1, IntPtr.Zero); base.Refresh(); } base.OnTextChanged(e); } public new bool WordWrap { get { return base.WordWrap; } set { base.WordWrap = value; } } public enum Languages { SQL, VBSCRIPT, CSHARP, JSHARP } private Languages language = Languages.CSHARP; public Languages Language { get { return this.language; } set { this.language = value; } } } }
时间: 2024-10-16 15:38:00