Richtextbox draw an rtf line
Asked Answered
S

2

20

I want to add a horizontal line to the RichTextBox as a delimiter of my text. I've found some examples of RTF code implementing a line and tried them in that way:

rtbResFile.Rtf = @"{\rtf1{\pard some text.\par}{\pard \brdrb \brdrs \brdrw10 \brsp20 \par}{\pard \par}{\pard some other text.\par}}";

This way implements creating a blank paragraph with border, so that should looks like a line. However it doesn't show anything. Just a blank paragraph. Even if I try to implement it in the way include line object

{\rtf1
{\pard some text.\par}
{\pard {\*\do\dobxcolumn\dobypara\dodhgt
        \dpline\dpxsize9200\dplinesolid\dplinew30}\par}
{\pard some other text.\par}
}

It still shows nothing. Does RichTextBox supports this? Or any other ways include the horizontal line in the rtf string?

Speedwell answered 30/11, 2011 at 10:58 Comment(0)
Z
17

There are a few different ways to create a horizontal line in RTF. Depending on the control or program being used your mileage may vary. RTF implementations in controls and programs tend to simply ignore markup that they don't know how to deal with. Note that the code samples below are snippets and not complete RTF documents. They will need to be embedded in a valid RTF document to work.

By drawing polygons:

{\pard{\*\do
\dobxcolumn \dobypara \dodhgt7200
\dpline \dpptx0 \dppty0 \dpptx7200
\dppty0 \dpx0 \dpy0 \dpxsize7200
\dpysize0 \dplinew15
\dplinecor0 \dplinecog0 \dplinecob0 }\par}

By inserting a blank paragraph with a border followed by another blank paragraph without a border:

{\pard \brdrb \brdrs \brdrw10 \brsp20 \par}
{\pard\par}

You can change the size and apparent positionof the line by setting indents on the paragraph:

{\pard \li2268 \ri567
\brdrb \brdrs \brdrw10 \brsp20 \par}
{\pard\par}

I highly recommend O'Reilly's RTF Pocket Guide for working with this stuff, which is where this came from.

Some further experimentation produced the code below, which does work in WordPad and the RichTextBox control.

{\pict\wmetafile8\picw26\pich26\picwgoal20000\pichgoal15 
0100090000035000000000002700000000000400000003010800050000000b0200000000050000
000c0202000200030000001e000400000007010400040000000701040027000000410b2000cc00
010001000000000001000100000000002800000001000000010000000100010000000000000000
000000000000000000000000000000000000000000ffffff00000000ff040000002701ffff0300
00000000
}

Basically, it involves inserting a 1x1 pixel image of a black dot and stretching it as needed by adjusting the height and width goals. The goal measurement is in twips. A twip is defined as being 1/1440 of an inch. It's a horrible hack, but it works.

Here is an example of the last snippet placed into a complete, valid RTF document that correctly displays on both WordPad and the RichTextBox control from Windows Forms:

{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Riched20 10.0.19041}\viewkind4\uc1 
\pard\sa200\sl276\slmult1\f0\fs22\lang9 Above\par
{\pict\wmetafile8\picw26\pich26\picwgoal20000\pichgoal15 
0100090000035000000000002700000000000400000003010800050000000b0200000000050000
000c0202000200030000001e000400000007010400040000000701040027000000410b2000cc00
010001000000000001000100000000002800000001000000010000000100010000000000000000
000000000000000000000000000000000000000000ffffff00000000ff040000002701ffff0300
00000000
}
\par
Below\par
}
Zareba answered 28/12, 2011 at 15:41 Comment(8)
Have you tried to implement this in RichTextBox of Windows.Forms? My question was dedicated to displaying rtf line in RichTextBox. I've described the same ways as yours in my question, and they doesn't work. If your one works - please provide an RTF string for RichTextBox.Speedwell
@Speedwell I have not tried these with a RichTextBox control. The reason I provided these is because I know they work elsewhere and aren't quite the same as what you've provided. From past experience with the RichTextBox control, it always pays off to try more than one way of declaring your intended result, because it can be a bit persnickety at times. Also, you might try making a new RTF document in Wordpad, creating your layout, and then opening the resulting document with Notepad to get the RTF you need. That generally works pretty well.Zareba
@Zareba these solutions won't render the line for me in OS X TextEdit.App which I had thought was a full-featured RTF editor. Which editor are you folks using? Any idea why I can't produce a line with these commands in my editor?Gibbsite
@Gibbsite These samples are meant to be part of an already existing RTF document and so need some additional RTF around them in order to not show up as plain text. Also, not every RTF editor implements all features and they tend to just ignore RTF code for things that they don't implement, i.e. these examples work fine in Microsoft Word, but not in WordPad.Zareba
@Matical Unfortunately, my experience has been that if it doesn't work in WordPad it won't work in a RichTextBox either. The only way I've ever been able to create a clean horizontal line in WordPad or the RichTextBox is to create a bitmap of a dot and then insert that into the RTF with the appropriate markup to stretch it. See the updated answer.Zareba
The last code sample (the one with the long hexadecimal string) works in RichtextBox RtfHospitable
This code worked in WordPad but in the RichText control (Win32) I tried it and ignores it. Typically what worked in WordPad worked in the control but for some reason this doesn't. Is there some property on the RichText control I need to enable?Sidelong
@Sidelong It works in the RichTextBox but needs to be embedded in a valid RTF document, i.e., {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033 ... and so on. If you tried to put only the code from the answer into the Rtf property of the control, the RTF won't validate and will result in nothing being displayed.Zareba
W
5

This function creates a horizontal bar that's just a picture. To create this picture, I just copied a horizontal bar from Visio into an RTF textbox, and then viewed the underlying RTF. Thus, it's possible to insert any image in this manner.

The code below works by moving the cursor to the very end of the text, then setting the "selected" RTF to be the aforementioned bar image. The text is then unselected.

The code sets this bar to be centered, however by setting the centreText to an empty string (or just removing the code), left alignment will be maintained.

    /// <summary>
    /// Appends a horizontal bar at the end of the specified Rich Text Box
    /// </summary>
    /// <param name="rtb">Rich Text Box to which horizontal bar is to be added</param>
    private void AppendHorizontalBar(RichTextBox rtb)
    {
        // Position cursor at end of text
        rtb.Select(rtb.TextLength, 0);
        int selStart = rtb.TextLength;
        int selEnd = rtb.TextLength;

        // Textbox may transform chars, so (end-start) != text.Length
        rtb.Select(selStart, selEnd - selStart);

        // This is the RTF section to add.
        string horizontalBarRtf = @"{\pict\wmetafile8\picw12777\pich117\picwgoal7245\pichgoal60 0100090000035b00000004000800000000000400000003010800050000000b0200000000050000000c022100280e030000001e0008000000fa0200000300000000008000040000002d01000007000000fc020100000000000000040000002d010100080000002503020011001100170e110008000000fa0200000000000000000000040000002d01020007000000fc020000ffffff000000040000002d01030004000000f0010000040000002701ffff030000000000}";
        string centreText = "\\pard\\qc"; // set this to empty string to keep existing text alignment

        // Wrap to-add RTF section in RTF tag
        rtb.SelectedRtf = String.Format("{{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033\\uc1 {0} {1} \\line}}", centreText, horizontalBarRtf);

        // Leave no text selected
        rtb.SelectionLength = 0;
    }
Whiplash answered 16/2, 2016 at 23:57 Comment(6)
this works fine.. but it adds line at the center of the richtextbox, not full length also.Alexandrite
@DeepakRaj - See the comment at declaration of centreText . Just set that to an empty string to maintain existing text justification. Also, as for the image, you can replace the image above with any image; in order to do so, paste an image into the Rich Text box, then view the RTF code to determine the serialized version of the image, and replace that section in the declaration of horizontalBarRtf.Whiplash
Is this line a typo ? rtb.Select(txtActivityLog.TextLength, 0);Weltanschauung
@WalterStabosz No, it's using the Select method to position the cursor at the end of all text, selecting 0 characters.Whiplash
@Whiplash I should have been more clear, what is txtActivityLog ? It doesn't appear anywhere else in your code.Weltanschauung
@WalterStabosz Aaah - I see the problem now. I'd created a function (for StackOverflow) based on code I'd mocked up elsewhere, and didn't replace all variables. I've corrected it now. Thanks for pointing that out.Whiplash

© 2022 - 2024 — McMap. All rights reserved.