//判断是否是中文
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