6

When I use the RichTextBox.Select(int start, int length) function to select text in a rich text box that contains hyperlinks, there is some shift in the selection when I try to select any text that is after the hyperlink.

When I remove the hyperlink, the selection works properly.

Edit: I use RichTextBox 5 (the default in Visual Studio is version 4)

public class RichText50W : RichTextBox
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr LoadLibrary(string lpFileName);
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams prams = base.CreateParams;
            if (LoadLibrary("msftedit.dll") != IntPtr.Zero)
            {
                prams.ClassName = "RICHEDIT50W";
            }
            return prams;
        }
    }
}

The problem occurs only with richtextbox 5+.

These images show the problem and the difference in behavior.

If you try this make sure to set HideSelection property of richtextboxes to "false".

Select functions are displayed on the buttons.

Select (10, 1)

For RTB5, 'e' in "Text" should be selected in the above image.

Select (40, 1)

Select (46, 1)

Apparently RTB5 selects some hidden text.

I need it to select based on the visible text only.

RTB 4 has problems when using tables, so I don't want to use it.

I use .NET 2.0

Edit: To try this in Visual Studio, start with the default richtextbox and change its declaration to RichText50W instead of RichTextBox

Also RichEdit 6 has the same issue.

Thanks

Jerry
  • 4,258
  • 3
  • 31
  • 58

2 Answers2

2

From my own experience, version "RICHEDIT50W" is horribly broken when used with embedded hyperlinks or hidden text (using rtf codes \v \v0).

In your v5 box, the Text.Length property reports 14 characters — what it displays. The TextLength property reports 51 characters. The SelectionStart and SelectionLength properties all report the "hidden text" numbers, but the control does not give you a way to get at the hidden text any longer. It means the "text" and related "text selection" information becomes unusable when your rich text has hidden characters.

I think the only solution is to not use the "RICHEDIT50W" version if there will be hidden characters or browse the market for a better rich text control.

LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • Unfortunately, richtext box 4 is very bad when it comes to tables, so it's not an option for me to use it. Do you know of another version that fixes these problems? – Jerry Oct 24 '12 at 16:46
  • @Jerry Yes, tables aren't great on v4. You would have to look at the market or maybe try the WPF version. [TextControl](http://www.textcontrol.com/en_US/) advertises a lot. I don't have experience with these 3rd party controls so I can't recommend one that fixes this exact issue you have. – LarsTech Oct 24 '12 at 16:51
  • @Jerry Shot in the dark: the only thing I can think of is to try the WPF version of the RichTextBox and put it in an ElementHost control. – LarsTech Apr 28 '13 at 17:01
  • @Jerry Hence the reference to the ElementHost. See [Put WPF control into a Windows Forms Form](http://stackoverflow.com/q/5053501/719186) – LarsTech Apr 28 '13 at 17:09
  • OK, just realized that, so I removed my comment. I'll have a look. – Jerry Apr 28 '13 at 17:11
  • This requires .NET 3.0 minimum. Unfortunately I use 2.0. – Jerry Apr 28 '13 at 17:15
  • 3
    @Jerry Things just seem to go from bad to worst for you on this topic. – LarsTech Apr 28 '13 at 17:20
  • Also, in Windows 10 (not 7) "RICHEDIT50W" will not call `ContentsResized` event when the text is changed. – Martin Braun Apr 15 '16 at 11:10
0

Only a little late. This may or may not help, I haven't used this control yet. Following code is copied from http://www.codeproject.com/Messages/3401956/NET-Richedit-Control.aspx. Note the // Check Unicode or ANSI system and set appropriate ClassName.

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace RichEditor
{
  public class RichTextBoxEx : RichTextBox
  {
    private IntPtr mHandle = IntPtr.Zero;

    protected override CreateParams CreateParams
    {
      get
      {
        //Prevent module being loaded multiple times.
        if (this.mHandle == IntPtr.Zero)
        {
          //load the library to obtain an instance of the RichEdit50 class.
          this.mHandle = LoadLibrary("msftedit.dll");
        }

        //If module loaded, reset ClassName.
        if (this.mHandle != IntPtr.Zero)
        {
          CreateParams cParams = base.CreateParams;

          // Check Unicode or ANSI system and set appropriate ClassName.
          if (Marshal.SystemDefaultCharSize == 1)
          {
            cParams.ClassName = "RichEdit50A";
          }
          else
          {
            cParams.ClassName = "RichEdit50W";
          }

          return cParams;
        }
        else // Module wasnt loaded, return default .NET RichEdit20 CreateParams.
        {
          return base.CreateParams;
        }
      }
    }


    ~RichTextBoxEx()
    {
      //Free loaded Library.
      if (mHandle != IntPtr.Zero)
      {
        FreeLibrary(mHandle);
      }
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr LoadLibrary(String lpFileName);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool FreeLibrary(IntPtr hModule);
  }
}
CAD bloke
  • 8,578
  • 7
  • 65
  • 114