RichTextBox着色与着色不闪

近来写的一个数据查询分析器意外的快捷,不到两晚工夫就搞定了。完成度相当的高。当然少不了关键字着色,不过着色的代码来自的网上,看了一下感觉过多的循环

//文本框改变事件    
            int index = this.richTextBox1.SelectionStart;  //记录修改的位置
            string[] keystr ={ "select ", "from ", "where ", " and ", " or ", " order ", " by ", " desc ", " when ", " case ",
  " then ", " end ", " on ", " in ", " is ", " as ", " else ", "left ", " join ", " not ", " null "," like "," exists " };
            for (int i = 0; i < keystr.Length; i++)
                this.getbunch(keystr[i], this.richTextBox1.Text, Color.Blue);

public int getbunch(string p, string s,Color pColor) //给关键字上色
        {
            int cnt = 0; int M = p.Length; int N = s.Length;
            char[] ss = s.ToCharArray(), pp = p.ToCharArray();
            if (M > N) return 0;
            for (int i = 0; i < N - M + 1; i++)
            {
                int j;
                for (j = 0; j < M; j++)
                {
                    if (ss[i + j] != pp[j]) break;
                }
                if (j == p.Length)
                {
                    this.richTextBox1.Select(i, p.Length);
                    this.richTextBox1.SelectionColor = pColor;
                    cnt++;
                }
            }
            return cnt;
        }

且关键字的边界也没有处理好。于是重新组织了判断关键字的代码,总的流程是先记录所有关键字及其所用颜色。从头到到尾取出每一个单词着色,以下是主体代码

/// <summary>
/// 着色
/// </summary>
public void RunColor()
{
    this.BeginUpdate();//停止绘制
    //文本框改变事件    
    int lastIndex = this.SelectionStart;  //记录修改的位置

    int index =0;
    int wordStart=-1;//找到的单词开始位置
    char[] text = this.Text.ToCharArray();//打散每一个字符
    StringBuilder sb = new StringBuilder();
    //尝试取出每一个单词
    while(index<text.Length)
    {
        char chk = text[index];
        if (WhiteSpaceChars.Contains(chk))//是否空白字符
        {
            if (wordStart >= 0)
            {
                //取出单词
                string code = sb.ToString();
                colorWords(code.ToLower(), wordStart);
                wordStart = -1;
            }
            else
            {
                //空白字符,未找到词开头,不需作任何处理
            }
        }
        else
        {
            //找到非空白字符
            if (wordStart == -1)//找到词开头了。
            {
                sb = new StringBuilder();
                wordStart = index;
            }
            sb.Append(chk);
        }
        index++;//下一字符
    }
    if (sb.Length > 0 && wordStart>=0)//最后一个词
    {
        string code = sb.ToString();
        colorWords(code.ToLower(),wordStart);
    }
    this.Select(lastIndex, 0);  //返回修改的位置
    this.SelectionColor = Color.Black;
    this.EndUpdate();//恢复绘制事件
}

以下是完整的RichTextbox的代码,解决着色不闪。着色方法RunColor需要外部调用,控件不会自动着色。

public class MyRichTextBox : RichTextBox
    {
        //private class paintHelper : Control
        //{
        //    public void DefaultWndProc(ref Message m)
        //    {
        //        this.DefWndProc(ref m);
        //    }
        //}

        private const int WM_PAINT = 0x000F;
        private int lockPaint;
        private bool needPaint;
        //private paintHelper pHelp = new paintHelper();

        public void BeginUpdate()
        {
            lockPaint++;
        }

        public void EndUpdate()
        {
            lockPaint--;
            if (lockPaint <= 0)
            {
                lockPaint = 0;
                if (needPaint)
                {
                    this.Refresh();
                    needPaint = false;
                }
            }
        }

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_PAINT:
                    if (lockPaint <= 0)
                    {
                        base.WndProc(ref m);
                    }
                    else
                    {
                        needPaint = true;
                        //pHelp.DefaultWndProc(ref m);
                    }
                    return;
            }

            base.WndProc(ref m);
        }

        Dictionary<string, Color> words = new Dictionary<string, Color>();
        /// <summary>
        /// 设置字符颜色
        /// </summary>
        /// <param name="pWords">关键字</param>
        /// <param name="pColor">所用颜色</param>
        /// <param name="isKeyWord">真时,替换之前设置的颜色。否的话,如果已设置相关关键字,忽略该设置</param>
        public void SetColorWord(IEnumerable<string> pWords, Color pColor,bool isKeyWord)
        {
            foreach (string one in pWords)
            {
                string low = one.ToLower();
                if (words.ContainsKey(low))
                {
                    if (isKeyWord)
                        words[low] = pColor;
                }
                else
                {
                    words.Add(low, pColor);
                }
            }
        }
        /// <summary>
        /// 着色
        /// </summary>
        public void RunColor()
        {
            this.BeginUpdate();//停止绘制
            //文本框改变事件    
            int lastIndex = this.SelectionStart;  //记录修改的位置

            int index =0;
            int wordStart=-1;//单词的开始位置
            char[] text = this.Text.ToCharArray();//打散每一个字符
            StringBuilder sb = new StringBuilder();
            //尝试取出每一个单词
            while(index<text.Length)
            {
                char chk = text[index];
                if (WhiteSpaceChars.Contains(chk))//是否空白字符
                {
                    if (wordStart >= 0)//空白字符,前面已找到单词的开始位置,这就是单词的结束了
                    {
                        //取出音词
                        string code = sb.ToString();
                        colorWords(code.ToLower(), wordStart);
                        wordStart = -1;
                    }
                    else
                    {
                        //空白字符,未找到词开头,不需作任何处理
                    }
                }
                else
                {
                    //找到非空白字符
                    if (wordStart == -1)//找到词开头了。
                    {
                        sb = new StringBuilder();
                        wordStart = index;
                    }
                    sb.Append(chk);
                }
                index++;//下一字符
            }
            if (sb.Length > 0 && wordStart>=0)//最后一个词
            {
                string code = sb.ToString();
                colorWords(code.ToLower(),wordStart);
            }
            this.Select(lastIndex, 0);  //返回修改的位置
            this.SelectionColor = Color.Black;
            this.EndUpdate();//恢复绘制事件
        }
        /// <summary>
        /// 给单词着色,非关键字改为黑色
        /// </summary>
        /// <param name="pChkWord"></param>
        /// <param name="pStart"></param>
        private void colorWords(string pChkWord,int pStart)
        {
            this.Select(pStart, pChkWord.Length);
            if (words.ContainsKey(pChkWord))
                this.SelectionColor = words[pChkWord];
            else
                this.SelectionColor = Color.Black;
        }
        /// <summary>
        /// 空白字符
        /// </summary>
        public static readonly char[] WhiteSpaceChars = new char[] { (char)0x00, (char)0x01, (char)0x02, (char)0x03, (char)0x04, (char)0x05,
            (char)0x06, (char)0x07, (char)0x08, (char)0x09, (char)0x0a, (char)0x0b, (char)0x0c, (char)0x0d, (char)0x0e, (char)0x0f,
            (char)0x10, (char)0x11, (char)0x12, (char)0x13, (char)0x14, (char)0x15, (char)0x16, (char)0x17, (char)0x18, (char)0x19, (char)0x20,
            (char)0x1a, (char)0x1b, (char)0x1c, (char)0x1d, (char)0x1e, (char)0x1f, (char)0x7f, (char)0x85, (char)0x2028, (char)0x2029 };
    }
时间: 2024-10-06 01:41:49

RichTextBox着色与着色不闪的相关文章

[WebGL入门]二十四,补色着色

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正. 本次的demo的运行结果 着色方法 上次介绍了反射光,反射光是实现光泽的不可缺少的概念,到此为止,基本的光照效果都已经封装完毕了. 光照的效果主要就是扩散光,环境光和反射光三种方法,灵活运用这三种光照,应该就能实现非常逼真的照明效果了. 前几篇一直在说光照,这次稍微换个视点,看一下着色,着色是

GPU渲染管线与可编程着色器

本文由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/71978861 这篇文章是解析计算机图形学界"九阴真经总纲"一般存在的<Real-Time Rendering 3rd>系列文章的第三篇.将带来RTR3第三章内容"Chapter 3 The Graphics Processing Unit 图形处理器"的总结.概括与提炼. 这章的主要内容是介绍G

OpenGL ES学习笔记(二)&mdash;&mdash;平滑着色、自适应宽高及三维图像生成

首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <Android学习笔记--OpenGL ES的基本用法.绘制流程与着色器编译>中实现了OpenGL ES的Android版HelloWorld,并且阐明了OpenGL ES的绘制流程,以及编译着色器的流程及注意事项.本文将从现实世界中图形显示的角度,说明OpenGL ES如何使得图像在移动设备上显示的更加真实.首先,物体有各种颜色

nBodyCS&lt;I&gt;学习笔记之计算着色器

nBodyCS<I>学习笔记之计算着色器 Nvidia-SDK(1) 版权声明:本文为博主原创文章,未经博主允许不得转载. DirectX一直是Windows上图形和游戏开发的核心技术.DirectX提供了一种在显卡上运行的程序--着色器(Shader).从DirectX11开始,DirectX增加了一种计算着色器(Compute Shader),它是专门为与图形无关的通用计算设计的.因此DirectX就变成了一个通用GPU计算的平台.鉴于GPU拥有极其强大的并行运算能力,学习使用Direct

DirectX学习笔记(五):利用平面着色和Gouraud着色模式绘制具有颜色的三角形

前言: 图元的颜色是由构成该图元的顶点的颜色所决定的,而物体是由图元索组成.那么如果我们要绘制一个具有颜色的三角形,我们就需要为三角形图元顶点附加颜色属性. 1.Direct3D中颜色的表示: 在Direct3D中,颜色用RGB来表示(这个大家都知道,咳咳.)通畅人为颜色可以分为红色(red).绿色(green).蓝色(bule).这三个分量进行混合,以达到我们想要的颜色取得目的.RGB的数据可以用两种方式来进行存储一种是D3DCOLOR ,另一种是:DWORD.这是因为D3DCOLOR完全等同

顶点着色器+片段着色器

一: 着色器 着色器只是一种把输入转化为输出的程序.着色器也是一种非常独立的程序,因为它们之间不能相互通信:它们之间唯一的沟通只有通过输入和输出. 在最简配置下,至少都得有两个着色器:一个叫顶点着色器(vertex shader),它将作用于每个顶点上:另一个叫片段着色器(fragment shader),它将作用于每一个采样点.我们采用4倍抗锯齿,因此每个像素有四个采样点. 如果我们打算从一个着色器向另一个着色器发送数据,我们必须在发送方着色器中声明一个输出,在接收方着色器中声明一个类似的输入

JDK11 | 第七篇 : ZGC 垃圾收集器

一.简介 Java 11包含一个全新的垃圾收集器--ZGC,它由Oracle开发,承诺在数TB的堆上具有非常低的暂停时间. 在本文中,我们将介绍开发新GC的动机,技术概述以及由ZGC开启的一些可能性. 那么为什么需要新GC呢?毕竟Java 10已经有四种发布多年的垃圾收集器,并且几乎都是无限可调的. 换个角度看,G1是2006年时引入Hotspot VM的.当时最大的AWS实例有1 vCPU和1.7GB内存,而今天AWS很乐意租给你一个x1e.32xlarge实例,该类型实例有128个vCPU和

polay定理总结

参考资料:polay定理 感觉最近一直容易遇见这种题目....... 稍微复杂一点的就不太会 先是一个总结出来的定理: 用一个最简单的例子来说明 对2*2的方阵用黑白两种颜色涂色,问能得到多少种不同的图像?经过旋转使之吻合的两种方案,算是同一种方案. 设G={p1,p2,-,pg}是Ω上的一个置换群比如置换群G={转0°,转90°,转180°,转270°} C(pk)是置换pk的循环的个数 G1置换{转0°  }的循环节是4, {(1),(2),(3),(4)} G2置换{转90° }的循环节是

[WebGL入门]十五,为多边形涂抹颜色(顶点颜色的指定)

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正. 本次的demo的运行结果 增加顶点属性的个数 上次,终于绘制了一个三角形,但是只绘制了一个纯白色的多边形.这次,给多边形的顶点中添加颜色属性,基本上做的事情和上一篇文章一样,只是稍微增加点步骤而已.首先,就像以前多次重复的那样,顶点可以包含很多种情报(参考:顶点缓存和基础),而且每一个情报叫做