繁体   English   中英

RichTextBox中的自定义链接

[英]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;
    }
}

它处理检测以#开头的单词,并在鼠标悬停在它们上方时使鼠标光标成为一只手。 但是,我有以下两个问题:

  1. 如果我尝试为richTextBox1实现双击事件,我可以检测单击单词的时间,但是该单词是突出显示(选中),我想避免。 我可以通过选择文本的结尾以编程方式取消选择它,但这会导致闪烁,我想避免。 有什么方法可以做到这一点?
  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM