分享
 
 
 

用c#实现的语法高亮控件

王朝c#·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

因为工作需要,用c#实现了一个能够对vbscript,c#,j#,sql显示语法高亮的文本编辑控件。这里详细介绍一下它的原理。

该控件是从RichTextBox继承下来,以xml格式存储各种语言的关键字。然后重写RichTextBox的OnTextChanged方法,在该方法中对输入文本进行解析,并对关键字进行着色。源代码点击这里下载。

xml文件格式如下,这里仅以j#为例。caseSensitive代表该语言是否大小写敏感。当然,由于本人懒惰成性,关键字是从网上搜集别人整理好的,如有遗漏,概不负责:)

如果需要解析其他语言,请添加相应的xml文件,并修改枚举类型Languages以及Parser类的构造函数中的相应代码。已知bug:当两个词是由括号分割的时候,程序无法识别。比如Function foo(integer i),程序会把foo(integer当作一个词。当然这里有两个解决办法,一个是程序自动进行语法排版,在括号前后自动插入空格;另一个是对括号进行解析。也许以后有空的时候我会加上。

<?xml version="1.0" encoding="utf-8" ?>

<definition name="J#" caseSensitive="true">

<word>private</word>

<word>protected</word>

<word>public</word>

<word>namespace</word>

<word>class</word>

<word>var</word>

<word>for</word>

<word>if</word>

<word>else</word>

<word>while</word>

<word>switch</word>

<word>case</word>

<word>using</word>

<word>get</word>

<word>return</word>

<word>null</word>

<word>void</word>

<word>int</word>

<word>string</word>

<word>float</word>

<word>this</word>

<word>set</word>

<word>new</word>

<word>true</word>

<word>false</word>

<word>const</word>

<word>static</word>

<word>package</word>

<word>function,</word>

<word>internal</word>

<word>extends</word>

<word>super</word>

<word>import</word>

<word>default</word>

<word>break</word>

<word>try</word>

<word>catch</word>

<word>finally</word>

<word>+</word>

<word>-</word>

<word>=</word>

</definition>

Parser类是负责对xml流进行解析,并包含一个方法来判断一个字符串是不是关键字。详细的代码和注释如下:

using System;

using System.Xml;

using System.IO;

using System.Collections;

using System.Reflection;

namespace SyntaxEditor

{

/// <summary>

/// Parser 的摘要说明。

/// </summary>

public class Parser

{

private XmlDocument xd=null;

private ArrayList al=null; //对xml流解析后,会把每一个关键字字符串放入这个容器中

private bool caseSensitive=false; //记录当前语言大小写敏感否

internal Parser(SyntaxEditor.Languages language) //构造函数接受一个枚举变量

{

//

// TODO: 在此处添加构造函数逻辑

//

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;

}

Stream strm = asm.GetManifestResourceStream(asm.GetName().Name + "."+filename); //取得xml流

//Reads the contents of the embedded file.

StreamReader reader= new StreamReader(strm); //下面的代码解析xml流

xd=new XmlDocument();

xd.Load(reader);

al=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);

}

this.caseSensitive=bool.Parse(root.Attributes["caseSensitive"].Value);

}

public bool IsKeyWord(string word) //判断字符串是否为关键字

{

bool rtn=false;

for(int i=0;i<al.Count;i++)

{

if(string.Compare(word,al[i].ToString(),!caseSensitive)==0)

{

rtn=true;

break;

}

}

return rtn;

}

}

}

控件类代码如下。

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 SyntaxEditor

{

/// <summary>

/// UserControl1 的摘要说明。

/// </summary>

public class SyntaxEditor : System.Windows.Forms.RichTextBox

{

/// <summary>

/// 必需的设计器变量。

/// </summary>

private System.ComponentModel.Container components = null;

//使用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()

{

//

// SyntaxEditor

//

this.Name = "SyntaxEditor";

}

#endregion

//重写基类的OnTextChanged方法。为了提高效率,程序是对当前文本插入点所在行进行扫描,

//以空格为分割符,判断每个单词是否为关键字,并进行着色。

protected override void OnTextChanged(EventArgs e)

{

if(base.Text!="")

{

int selectStart=base.SelectionStart;

int 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[]{' '});

Parser parser=new Parser(this.language);

for(int i=0;i<words.Length;i++)

{

if(parser.IsKeyWord(words[i]))

{

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.SelectionColor=Color.Blue;

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;}

}

public enum Languages

{

SQL,

VBSCRIPT,

CSHARP,

JSHARP

}

private Languages language=Languages.SQL;

public Languages Language

{

get{return this.language;}

set{this.language=value;}

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有