[英]Custom links in RichTextBox
假设我希望以#
开头的每个单词都能在双击时生成一个事件。 为此,我实现了以下测试代码:
private bool IsChannel(Point position, out int start, out int end)
{
if (richTextBox1.Text.Length == 0)
{
start = end = -1;
return false;
}
int index = richTextBox1.GetCharIndexFromPosition(position);
int stop = index;
while (index >= 0 && richTextBox1.Text[index] != '#')
{
if (richTextBox1.Text[index] == ' ')
{
break;
}
--index;
}
if (index < 0 || richTextBox1.Text[index] != '#')
{
start = end = -1;
return false;
}
while (stop < richTextBox1.Text.Length && richTextBox1.Text[stop] != ' ')
{
++stop;
}
--stop;
start = index;
end = stop;
return true;
}
private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
textBox1.Text = richTextBox1.GetCharIndexFromPosition(new Point(e.X, e.Y)).ToString();
int d1, d2;
if (IsChannel(new Point(e.X, e.Y), out d1, out d2) == true)
{
if (richTextBox1.Cursor != Cursors.Hand)
{
richTextBox1.Cursor = Cursors.Hand;
}
}
else
{
richTextBox1.Cursor = Cursors.Arrow;
}
}
它处理检测以#
开头的单词,并在鼠标悬停在它们上方时使鼠标光标成为一只手。 但是,我有以下两个问题:
richTextBox1
实现双击事件,我可以检测单击单词的时间,但是该单词是突出显示(选中),我想避免。 我可以通过选择文本的结尾以编程方式取消选择它,但这会导致闪烁,我想避免。 有什么方法可以做到这一点? GetCharIndexFromPosition
方法返回最接近游标的字符的索引。 这意味着,如果我的RichTextBox包含的唯一内容是以#
开头的单词,则无论富文本控件位于何处,光标都将成为一只手。 我怎样才能使它只是一只手,当它悬停在我感兴趣的单词的实际单词或字符上时? 实现的URL检测也部分地受到这个问题的困扰。 如果我启用URL检测并且只在富文本编辑器中编写www.test.com
,只要它位于链接上或下方 ,光标就会成为一只手。 但是,如果它位于链接的右侧,则不会是一只手。 即使使用此功能我也很好,如果将光标放在手上,并且只有在文本上证明它太难。 我猜我不得不求助于某种Windows API调用,但我真的不知道从哪里开始。
我正在使用Visual Studio 2008,我想自己实现它。
更新:如果我可以通过双击,只有通过拖动鼠标光标并以编程方式选择文本,就可以解决闪烁问题。 这更容易实现吗? 因为我真的不在乎是否可以通过双击来选择文本。
在第(2)点你可以尝试:
if (richTextBox1.Text.Length == 0){ ... }
之后if (richTextBox1.Text.Length == 0){ ... }
//get the mouse point in client coordinates
Point clientPoint = richTextBox1.PointToClient(richTextBox1.PointToScreen(position));
int index = richTextBox1.GetCharIndexFromPosition(position);
//get the position of the closest char
Point charPoint = richTextBox1.GetPositionFromCharIndex(index);
bool notOnTheSameLine = ((clientPoint.Y < charPoint.Y) || (clientPoint.Y > charPoint.Y + richTextBox1.Font.Height));
bool passedTheWord = (clientPoint.X > charPoint.X + richTextBox1.Font.SizeInPoints);
if (notOnTheSameLine || passedTheWord)
{
start = end = -1;
return false;
}
对于点(1),可能有一种不同的方式来跟踪链接而不是dbl-click? 也许cntl-click会避免单词被选中的问题......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.