Custom links in RichTextBox

Posted by IVlad on Stack Overflow See other posts from Stack Overflow or by IVlad
Published on 2010-04-02T15:54:09Z Indexed on 2010/04/02 21:13 UTC
Read the original article Hit count: 409

Filed under:
|
|
|

Suppose I want every word starting with a # to generate an event on double click. For this I have implemented the following test code:

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;
    }
}

This handles detecting words that start with # and making the mouse cursor a hand when it hovers over them. However, I have the following two problems:

  1. If I try to implement a double click event for richTextBox1, I can detect when a word is clicked, however that word is highlighted (selected), which I'd like to avoid. I can deselect it programmatically by selecting the end of the text, but that causes a flicker, which I would like to avoid. What ways are there to do this?
  2. The GetCharIndexFromPosition method returns the index of the character that is closest to the cursor. This means that if the only thing my RichTextBox contains is a word starting with a # then the cursor will be a hand no matter where on the rich text control it is. How can I make it so that it is only a hand when it hovers over an actual word or character that is part of a word I'm interested in? The implemented URL detection also partially suffers from this problem. If I enable detection of URLs and only write www.test.com in the rich text editor, the cursor will be a hand as long as it is on or below the link. It will not be a hand if it's to the right of the link however. I'm fine even with this functionality if making the cursor a hand if and only if it's on the text proves to be too difficult.

I'm guessing I'll have to resort to some sort of Windows API calls, but I don't really know where to start.

I am using Visual Studio 2008 and I would like to implement this myself.

Update: The flickering problem would be solved if I could make it so that no text is selectable through double clicking, only through dragging the mouse cursor. Is this easier to achieve? Because I don't really care if one can select text or not by double clicking in this case.

© Stack Overflow or respective owner

Related posts about c#

Related posts about .NET