zoukankan      html  css  js  c++  java
  • RichTextBox实现关键字自定义颜色显示(C#)

    现在的很多编辑工具都能实现代码中关键字的高亮显示,自己一时好玩也就随便写了一个:

    首先建立一个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;}
    }

    }
    }

     

    这个时候你只要保证XML文件和exe或者数据集(如果你打算这样做)在同一个目录就可以了。

    呵呵 很简单哦,看样子写个C语言编辑环境也不是很难哦 呵呵~

    我尝试去掉API在MONO上面编译,可惜MONO并没有支持RichTextBox控件,既然只能在Win上面运行,所以还是加上API好了,可以减少屏幕闪动感觉.

  • 相关阅读:
    安装 pptpd 服务
    profile bashrc bash_profile 之间的区别和联系
    11款基于Javascript的文件管理器
    C/C++学习之static_cast和dynamic_cast、reinterpret_cast
    VS.Net中程序集的Debug版本和Release版本的区别
    .net4.0以下的CookieContainer存在一个bug.即主域和子域cookie互访有问题。
    学习C# delegate和C# event
    使用log4net记录日志到数据库(含有自定义属性)
    c#获取本机ip地址|获取本机的本地上网IP地址
    Java 跨语言实现方案
  • 原文地址:https://www.cnblogs.com/top5/p/2034247.html
Copyright © 2011-2022 走看看