views:

2880

answers:

9

We are having problems with the Windows.Forms.RichTextBox control in Visual Studio 2008.

We are trying to display text supplied as an RTF file by a 3rd party in a windows forms application (.NET 3.5). In this RTF text file there are tables, which contain text that spans multiple lines. The RTF file displays correctly when opened with either WordPad or Word 2003.

However, when we load the RTF file into the RichTextBox control, or copy & paste the whole text (including the table) into the control, the table does not display correctly - the cells are only single line, without wrapping.

Here are links to images showing the exact problem:

I have googled for solutions and 3rd party .net RTF controls without success. I have found this exact problem asked on another forum without an answer (in fact that's where the link to the images come from) so I'm hoping stack overflow does better ;-)

My preferred solution would be to use code or a 3rd party control that can correctly render the RTF. However, I suspect the problem is that the RichTextBox control only supports a subset of the full RTF spec, so another option would be to modify the RTF directly to remove the unsupported control codes or otherwise fix the RTF file itself (in which case any information as to what control codes need to be removed or modified would be a huge help).

A: 

Wordpad is generally a very thin wrapper over the rich edit control, so if it appears properly there then Windows should be able to handle it.

Perhaps you're instantiating the wrong version of the rich edit control? There have been many, and Windows continues to supply the older ones for backwards compatibility. http://msdn.microsoft.com/en-us/library/bb787873(VS.85).aspx

Mark Ransom
But WordPad isn't written in .NET, so it would be using a different rich edit control wouldn't it?I suppose it is possible that the .NET RichTextBox control is a .NET wrapper around the native control, but I would have thought if that was the case then this problem would not be occurring.
Ben Robbins
+1  A: 

Can you use the old COM control instead of the new .NET control, or do you require a "pure" .NET solution?

In other words, go into the Visual Studio toolbox, right click, choose "Choose Items", look in the COM Components tab and check Microsoft Rich Textbox Control 6.0.

Joel Spolsky
Thanks Joel, I've just given that a go but unfortunately the COM control (which was hard to find because it is called "MSREdit") behaves exactly the same as the .Net one.That appears to confirm what I read while originally googling this problem - the .Net control is based on the COM control.
Ben Robbins
+2  A: 

The Rich Text box from .NET is extremely buggy.

In RTF, the way a table is defined is actually quite different from what you could expect if you are used to HTML.

HTML:

<table>
<tr>
    <td>Mycell</td>
</tr>
</table>

In RTF, a table is simply a series of paragraphs with control words defining rows, cells, borders. There is no group tag for the start/end of a table.

RTF:

\trowd\trgraph \cellx1000 Mycell \cell\row\pard\par

If you want to add a paragraph inside a cell, you use \par and the control \intbl (in table) to indicate the paragraph is inside the table.

.NET RTB can handle only a very small subset of RTF control words and doesn't support the vast majority of available commands. By the looks of things, \intbl is part of the long long list of control words it doesn't support, and if it actually parses \par at that point, the display is trashed.

Unfortunately, I don't have a solution for that but I hope the small explanation above helps you make some sense of the problem.

Don't put too much faith on my RTF sample. It works, but it's absolutely bare-bones. You can download the RTF specifications from Microsoft's website: Word 2007 RTF specs.

Sylverdrag
+1  A: 

Answering my own question here, but only due to the help from Joel and sylverdrag...

The short answer is that both the .Net and underlying COM RichTextBox do not support word wrap in tables. I ended up knocking up a test application and using both the COM and .Net RichTextBox controls and they both exhibited the same (broken) behaviour.

I also downloaded the RTF spec from the link supplied by sylverdrag and after tinkering with hand-made RTF documents in MS Word and RichTextEdit controls, I can confirm that TichTextBox does not correctly support the \intbl control word - which is required for word wrap in tables.

There appear to be three possible solutions:

  1. Use TX Text Control. I have confirmed this works using a trial version but it is expensive - prices start at US$549 per developer.

  2. Use an embedded MS Word instance as discussed on Code Project. Note that the code example provided on Code Project didn't work out of the box but I did get it working with Office 2003 & VS 2008. After much mucking around we hit an unexpected show stopper - we want the document to be read-only so we Protect() the document. While this works, when a user tries to edit the document the MS Word "Protect Document" side bar pops out from the right hand side of the control. We can't live with this and I was not able to turn it off (and from googling it looks like I'm not alone).

  3. Give up on RTF and use HTML instead and then render the document in a WebBrowser control instead of a RichTextEdit control. That is the option we are taking as it turns out the source document is available in either format.

Ben Robbins
+1  A: 

Hi, there's a solution. Step 1, Use the old COM Microsoft Rich Textbox Control 6.0; Step 2, Make a copy of Windows\System32\MsftEdit.dll and then rename it to riched20.dll; Step 3, Copy riched20.dll to your app folder such as bin\bebug. This works fine, table displays correctly.

Thanks Sunshine. I haven't tried this and unfortunately it probably isn't an option with the deployment limitations we have. It's worth noting for next time and also to help anyone reading this down the track.
Ben Robbins
A: 

Thanks. Good idea! I'll use WebBrowser as well.

A: 

Hi,

This is not a issue of RitchText Control provided in .net . some Ritchtext rules (Ritchtext Synatax) has been changed in new version of Ms-office (2007). however the component used in .net cannot update to cater the new rules so the issue occours.

Anand

Anand
+2  A: 

Hi I found the solution from another page

http://stackoverflow.com/questions/1928853/why-isnt-the-richtextbox-displaying-this-table-properly

tt
+1  A: 

Just create a new Control. It works fine for me.

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

public class RichTextBox5 : RichTextBox {
  private static IntPtr moduleHandle;

  protected override CreateParams CreateParams {
    get {
      if (moduleHandle == IntPtr.Zero) {
        moduleHandle = LoadLibrary("msftedit.dll");
        if ((long)moduleHandle < 0x20) throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not load Msftedit.dll");
      }
      CreateParams createParams = base.CreateParams;
      createParams.ClassName = "RichEdit50W";
      if (this.Multiline) {
        if (((this.ScrollBars & RichTextBoxScrollBars.Horizontal) != RichTextBoxScrollBars.None) && !base.WordWrap) {
          createParams.Style |= 0x100000;
          if ((this.ScrollBars & ((RichTextBoxScrollBars)0x10)) != RichTextBoxScrollBars.None) {
            createParams.Style |= 0x2000;
          }
        }
        if ((this.ScrollBars & RichTextBoxScrollBars.Vertical) != RichTextBoxScrollBars.None) {
          createParams.Style |= 0x200000;
          if ((this.ScrollBars & ((RichTextBoxScrollBars)0x10)) != RichTextBoxScrollBars.None) {
            createParams.Style |= 0x2000;
          }
        }
      }
      if ((BorderStyle.FixedSingle == base.BorderStyle) && ((createParams.Style & 0x800000) != 0)) {
        createParams.Style &= -8388609;
        createParams.ExStyle |= 0x200;
      }
      return createParams;
    }
  }
  // P/Invoke declarations
  [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  private static extern IntPtr LoadLibrary(string path);

}
Vildan