问题
I found some old code written by NoBugz (Hans Passant) which, if I understand, forces the richtextbox to use RTF 5.0 instead of 4.0. Basically it's just a class which inherits RichTextBox
and overrides the CreateParams
property as such
private static IntPtr moduleHandle;
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern IntPtr LoadLibrary(string lpFileName);
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;
}
}
When I do perform this override, I cannot get my RTF to display past the first line. e.g.
string rtf = @"{\rtf1\ansi\deff0{\fonttbl{\f0 Arial;}{\f1 Courier New;}}\viewkind4\uc1\pard\lang1033\f0\fs20 {\pard\f0\ul\b Activated Partial Thromboplastin Time\b0 : Collected: "
+ @"8/21/2012 4:15:00 AM\ulnon\f0\par}\par\pard\lang1033\f0\fs20 {\trowd"
+ @"\trql\trgaph100\trrh280\trleft0\intbl"
+ @"\cellx4000"
+ @"\cellx9500"
+ @"Activated Partial Thromboplastin Time\cell"
+ @"36.8 Seconds\cell"
+ @"\intbl\row}";
CustomRtb cRtb = new CustomRtb();
cRtb.Rtf = rtf;//Only the first line shows in the form...
Is the new standard just much less forgiving of Rtf errors or what? I need the prettier table formatting offered by 5.0
UPDATE
The data displays if I change
+ @"\trql\trgaph100\trrh280\trleft0\intbl"
to
+ @"\trql\trgaph100\trrh280\trleft0"
Upon further testing I found that the RTF looks good in MS Word. In fact, our code generates the RTF with MsftEdit as indicated here:
{\*\generator Msftedit 5.41.21.2510;}
. I open up the actual RTF in Word and it looks fine. I use this code and it pretty much matches what I see in word. I just need to remove some borders. I'm going to have to do some deeper digging to see why Msftedit is generating the RTF to be slightly mal-aligned in the tables. But yea, overall this question is just getting beyond the scope of what I can do in SO.
回答1:
Handcrafting RTF in code is not an easy thing to do. You have to pay attention to those escape characters and spaces become real important, too.
The easiest way to tackle this is to reverse engineer it. Open up Microsoft Word, create a table, format it to your liking, then copy paste it into your CustomRtb control and look at the resulting RTF code that it produced:
private string Sample() {
StringBuilder sb = new StringBuilder();
sb.Append(@"{\rtf1\ansi\deff0");
sb.Append(@"{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}");
sb.Append(@"{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fnil\fcharset0 Microsoft Sans Serif;}}");
sb.Append(@"{\*\generator Msftedit 5.41.21.2510;}");
sb.Append(@"\viewkind4\uc1\pard\sa200\sl276\slmult1\lang1033\ul\b\f0\fs20");
sb.Append(@" Activated Partial Thromboplastin Time\b0 : Collected:8/21/2012 4:15:00 AM\par");
sb.Append(@"\trowd\trgaph108\trleft-108\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10");
sb.Append(@" \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl108\trpaddr108\trpaddfl3\trpaddfr3");
sb.Append(@"\clbrdrl\brdrw10\brdrs\clbrdrt\brdrw10\brdrs\clbrdrr\brdrw10\brdrs\clbrdrb\brdrw10\brdrs");
sb.Append(@" \cellx4680\clbrdrl\brdrw10\brdrs\clbrdrt\brdrw10\brdrs\clbrdrr\brdrw10\brdrs\clbrdrb\brdrw10\brdrs");
sb.Append(@" \cellx9468\pard\intbl\ulnone Actived Partial Thromboplastin Time");
sb.Append(@" \cell\pard\intbl\qr 36.8 Seconds\cell\row\pard\sa200\sl276\slmult1\par");
sb.Append(@"\pard\f2\fs17\par");
sb.Append(@"}");
return sb.ToString();
}
As you can see, RTF code can get rather chatty. This created a line of text with bold and underline, then a two column table with bordered cells, the second cell being right aligned.
来源:https://stackoverflow.com/questions/12148731/richtextbox-does-not-display-all-data-when-i-override-createparams