//判断是否是中文
        public bool IsChina(char c)
        {

bool BoolValue = false;
            if (Convert.ToInt32(c) < Convert.ToInt32(Convert.ToChar(128)))
            {
                BoolValue = false;
            }
            else
            {
                return BoolValue = true;
            }
            return BoolValue;
        }
        //获取字符串中文数量
        public int GetLineIsChinese(Line list)
        {
            int isChinese = 0;
            for (int num = 0; num < list.Count;num++ )
            {
                if (IsChina(list[num].c))
                {
                    isChinese++;
                }
            }
            return isChinese;
        }
        //获取中文和英文差异宽度
        public int GetCharDiffWidth()
        {
            SizeF sizef = GetCharSize(this.Font, '中');//new Font("宋体", 10)
            int len = (int)sizef.Width - CharWidth;
            return len;
        }

//draw selection
            if (!Selection.IsEmpty && lastChar >= firstChar)
            {
                e.Graphics.SmoothingMode = SmoothingMode.None;
                var textRange = new Range(this, from + firstChar, iLine, from + lastChar + 1, iLine);
                textRange = Selection.GetIntersectionWith(textRange);
                if (textRange != null && SelectionStyle != null)
                {
                    int chineseCount= GetLineIsChinese(line);
                    int diffWidths = GetCharDiffWidth()*chineseCount;
                    diffWidth = diffWidths;
                    SelectionStyle.Draw(e.Graphics, new Point(startX + (textRange.Start.iChar - from) * CharWidth, y),
                                        textRange);
                    diffWidth = 0;
                }
            }

public override void Draw(Graphics gr, Point position, Range range)
        {
            //draw background
            if (BackgroundBrush != null)
            {
             
                Rectangle rect = new Rectangle(position.X, position.Y, (range.End.iChar - range.Start.iChar) * range.tb.CharWidth+FastColoredTextBox.diffWidth, range.tb.CharHeight);
                if (rect.Width == 0)
                    return;
                gr.FillRectangle(BackgroundBrush, rect);
            }
        }

diffWidth  这是公共变量,放在FastColoredTextBox类的公共变量声明里面

public static int diffWidth = 0;

/*****************************/

/*  该代码用于准确定位字,主要是因为中文不能准确定位  */

/*****************************/

/// <summary>
        /// Gets nearest line and char position from coordinates
        /// </summary>
        /// <param name="point">Point</param>
        /// <returns>Line and char position</returns>
        public Place PointToPlace(Point point)
        {
#if debug
            var sw = Stopwatch.StartNew();
#endif
            point.Offset(HorizontalScroll.Value, VerticalScroll.Value);
            point.Offset(-LeftIndent - Paddings.Left, 0);
            int iLine = YtoLineIndex(point.Y);
            int y = 0;

for (; iLine < lines.Count; iLine++)
            {
                y = LineInfos[iLine].startY + LineInfos[iLine].WordWrapStringsCount * CharHeight;
                if (y > point.Y && LineInfos[iLine].VisibleState == VisibleState.Visible)
                    break;
            }
            if (iLine >= lines.Count)
                iLine = lines.Count - 1;
            if (LineInfos[iLine].VisibleState != VisibleState.Visible)
                iLine = FindPrevVisibleLine(iLine);
            //
            int iWordWrapLine = LineInfos[iLine].WordWrapStringsCount;
            do
            {
                iWordWrapLine--;
                y -= CharHeight;
            } while (y > point.Y);
            if (iWordWrapLine < 0) iWordWrapLine = 0;
            //
            int start = LineInfos[iLine].GetWordWrapStringStartPosition(iWordWrapLine);
            int finish = LineInfos[iLine].GetWordWrapStringFinishPosition(iWordWrapLine, lines[iLine]);
            var x = (int)Math.Round((float)point.X / CharWidth);
            x = x < 0 ? start : start + x;
            if (x > finish)
                x = finish + 1;
            if (x > lines[iLine].Count)
                x = lines[iLine].Count;

if (lines[iLine].Count > 0)
            {
                x = GetXWidth(lines[iLine], point.X);
            }

#if debug
            Console.WriteLine("PointToPlace: " + sw.ElapsedMilliseconds);
#endif

return new Place(x, iLine);
        }

private Place PointToPlaceSimple(Point point)
        {
            point.Offset(HorizontalScroll.Value, VerticalScroll.Value);
            point.Offset(-LeftIndent - Paddings.Left, 0);
            int iLine = YtoLineIndex(point.Y);
            var x = (int)Math.Round((float)point.X / CharWidth);
            Line line = lines[iLine];
            if (x < 0) x = 0;

if (line.Count > 0)
            {
                x = GetXWidth(lines[iLine], point.X);
            }
            return new Place(x, iLine);
        }
        //计算x轴应该显示第几个字的宽度
        public int GetXWidth(Line line,int x)
        {
            int iChar = 0;
            int len = 0;
            for (int num = 0; num < line.Count; num++)
            {
                if (len >= x)
                {
                    break;
                }
                if (IsChina(line[num].c))
                {
                    iChar += 2;
                    len += (GetCharDiffWidth() + CharWidth);
                }
                else
                {
                    iChar++;
                    len += CharWidth;
                }
            }
            return iChar;
        }

http://files.cnblogs.com/MyNameIsMT/FastColoredTextBox20140116.zip

修改FastColoredTextBox控件完成选择的更多相关文章

  1. Dbgrid控件多重选择的怪问题。BookMarkList,BookMark,使用书签,用的ADOQuery控件。100分送上,急阿!!!请高手帮忙!

    Dbgrid控件多重选择的怪问题.BookMarkList,BookMark,使用书签,用的ADOQuery控件.100分送上,急阿!!!请高手帮忙! ( 积分: 100 )<br />p ...

  2. QTableView表格控件区域选择-自绘选择区域

    目录 一.开心一刻 二.概述 三.效果展示 四.实现思路 1.绘制区域 2.绘制边框 3.绘制 五.相关文章 原文链接:QTableView表格控件区域选择-自绘选择区域 一.开心一刻 陪完客户回到家 ...

  3. 背水一战 Windows 10 (33) - 控件(选择类): ListBox, RadioButton, CheckBox, ToggleSwitch

    [源码下载] 背水一战 Windows 10 (33) - 控件(选择类): ListBox, RadioButton, CheckBox, ToggleSwitch 作者:webabcd 介绍背水一 ...

  4. 背水一战 Windows 10 (32) - 控件(选择类): Selector, ComboBox

    [源码下载] 背水一战 Windows 10 (32) - 控件(选择类): Selector, ComboBox 作者:webabcd 介绍背水一战 Windows 10 之 控件(选择类) Sel ...

  5. Winform中修改WebBrowser控件User-Agent的方法(已经测试成功)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  6. C# WPF 使用委托修改UI控件

    近段时间在自学WPF,是一个完全不懂WPF的菜鸟,对于在线程中修改UI控件使用委托做一个记录,给自已以后查询也给需要的参考: 界面只放一个RichTextBox,在窗体启动时开起两个线程,调用两个函数 ...

  7. 在.net中修改Webbrowser控件的IE版本

    根据32位.64位系统来分别修改对应的注册表路径的键值对,不需要重启程序. /// <summary> /// 修改Webbrowser控件模拟的IE版本 /// </summary ...

  8. android中动态修改ImageView控件的宽高度

    本例实现了动态修改ImageView控件的宽高度,有两个按钮,一个按钮实现放大image,一个按钮实现缩小image activity_main.xml <?xml version=" ...

  9. 修改static控件背景颜色和文字颜色

    当 static 控件或具有 ES_READONLY 风格的 edit 控件被绘制时,会向父窗口发送 WM_CTLCOLORSTATIC 消息.如果我们在窗口过程中处理该消息,就必须返回一个画刷句柄, ...

随机推荐

  1. Install Google Pinyin on Ubuntu 14.04

    Install Google Pinyin on Ubuntu 14.04 I've been spending more and more time on Ubuntu and I'm not us ...

  2. CSS小三角制作

    以下是参考资料: 好多种图形的:http://www.jb51.net/css/41448.html -------------------------------------15.11.12---- ...

  3. RMAN的实战篇--备份脚本

    案列一. 目标: 1.每天夜间1 点执行:2.数据库全备,同时备份控制文件及归档日志文件,备份文件保存至: /backup\目录下,并在完成归档日志文件备份后,自动删除已备份的归档日志:3.备份保留7 ...

  4. C语言语法之运算符及优先级

    注:该内容整理自以下链接. http://blog.csdn.net/huangblog/article/details/8271791 表:C语言运算符及优先级 优先级 运算符 名称或含义 使用形式 ...

  5. neon指令,注意事项

    1. vbic_s8 (int8x8_t a, int8x8_t b) 是  ~(ai & bi),一开始理解成  (~ai )& bi 导致出错 2.uint8x8_t vqshrn ...

  6. linux如何修改文件或目录的权限(chmod)

    chmod命令是linux上用于改变权限的命令,-R 是递归遍历子目录,因为你要操作的文件使用的*通配符.777,第一个7代表文件所属者的权限,第二个7代表文件所属者所在组的权限,第三个7代表其它用户 ...

  7. WPF:ListView 分组合并

    CollectionViewSource 绑定的是从数据库取出的数据ListBind 以DeptName为分组依据 <Window.Resources> <CollectionVie ...

  8. office openxml学习(一)

    以前用过,aspose.dll处理word ,excel,之后发现 npoi,使用了一段时间,总觉得是第三方,不明白底层的实现,直到最近发现了office openxml ,其实这个技术,很久以前就有 ...

  9. PostgreSQL的时间/日期函数使用 转

    http://www.cnblogs.com/mchina/archive/2013/04/15/3010418.html

  10. Java:多线程<一>

    程序运行时,其实是CPU在执行程序的进程,为了提高工作效率一个进程可以有多个线程. Java的多线程: 其实我们之前就见过Java的线程,main就是Java的一个线程,还有另一个条线程总是和main ...