本文转自:http://www.cnblogs.com/Dragon-China/archive/2008/01/13/651019.html
现在的很多编辑工具都能实现代码中关键字的高亮显示,自己一时好玩也就随便写了一个:
首先建立一个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 >
其中color指定了该关键字的颜色.
然后在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.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using System.Runtime.InteropServices; using HWND = System.IntPtr; namespace WindowsApplication1 { /// <summary> /// SyntaxEditor 的摘要说明。 /// </summary> public 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> protected override void Dispose( bool disposing ) { if ( disposing ) { if ( components != null ) components.Dispose(); } base .Dispose( disposing ); } #region 组件设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器 /// 修改此方法的内容。 /// </summary> private void InitializeComponent() { this .Name = " SyntaxEditor " ; } #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;} } } }