📄 richtextbox.cs
字号:
#endregion
#region Accessors
// TODO: This can be ommitted along with RemoveBadCharacters
// Overrides the default implementation of RTF. This is done because the control
// was originally developed to run in an instant messenger that uses the
// Jabber XML-based protocol. The framework would throw an exception when the
// XML contained the null character, so I filtered out.
public new string Rtf
{
get {return RemoveBadChars(base.Rtf);}
set {base.Rtf = value;}
}
// The color of the text
public RtfColor TextColor
{
get {return textColor;}
set {textColor = value;}
}
// The color of the highlight
public RtfColor HiglightColor
{
get {return highlightColor;}
set {highlightColor = value;}
}
#endregion
#region Constructors
/// <summary>
/// Initializes the text colors, creates dictionaries for RTF colors and
/// font families, and stores the horizontal and vertical resolution of
/// the RichTextBox's graphics context.
/// </summary>
public MyExtRichTextBox() : base()
{
// Initialize default text and background colors
textColor = RtfColor.Black;
highlightColor = RtfColor.White;
// Initialize the dictionary mapping color codes to definitions
rtfColor = new HybridDictionary();
rtfColor.Add(RtfColor.Aqua, RtfColorDef.Aqua);
rtfColor.Add(RtfColor.Black, RtfColorDef.Black);
rtfColor.Add(RtfColor.Blue, RtfColorDef.Blue);
rtfColor.Add(RtfColor.Fuchsia, RtfColorDef.Fuchsia);
rtfColor.Add(RtfColor.Gray, RtfColorDef.Gray);
rtfColor.Add(RtfColor.Green, RtfColorDef.Green);
rtfColor.Add(RtfColor.Lime, RtfColorDef.Lime);
rtfColor.Add(RtfColor.Maroon, RtfColorDef.Maroon);
rtfColor.Add(RtfColor.Navy, RtfColorDef.Navy);
rtfColor.Add(RtfColor.Olive, RtfColorDef.Olive);
rtfColor.Add(RtfColor.Purple, RtfColorDef.Purple);
rtfColor.Add(RtfColor.Red, RtfColorDef.Red);
rtfColor.Add(RtfColor.Silver, RtfColorDef.Silver);
rtfColor.Add(RtfColor.Teal, RtfColorDef.Teal);
rtfColor.Add(RtfColor.White, RtfColorDef.White);
rtfColor.Add(RtfColor.Yellow, RtfColorDef.Yellow);
// Initialize the dictionary mapping default Framework font families to
// RTF font families
rtfFontFamily = new HybridDictionary();
rtfFontFamily.Add(FontFamily.GenericMonospace.Name, RtfFontFamilyDef.Modern);
rtfFontFamily.Add(FontFamily.GenericSansSerif, RtfFontFamilyDef.Swiss);
rtfFontFamily.Add(FontFamily.GenericSerif, RtfFontFamilyDef.Roman);
rtfFontFamily.Add(FF_UNKNOWN, RtfFontFamilyDef.Unknown);
// Get the horizontal and vertical resolutions at which the object is
// being displayed
using(Graphics _graphics = this.CreateGraphics())
{
xDpi = _graphics.DpiX;
yDpi = _graphics.DpiY;
}
}
/// <summary>
/// Calls the default constructor then sets the text color.
/// </summary>
/// <param name="_textColor"></param>
public MyExtRichTextBox(RtfColor _textColor) : this()
{
textColor = _textColor;
}
/// <summary>
/// Calls the default constructor then sets te text and highlight colors.
/// </summary>
/// <param name="_textColor"></param>
/// <param name="_highlightColor"></param>
public MyExtRichTextBox(RtfColor _textColor, RtfColor _highlightColor) : this()
{
textColor = _textColor;
highlightColor = _highlightColor;
}
#endregion
#region Append RTF or Text to RichTextBox Contents
/// <summary>
/// Assumes the string passed as a paramter is valid RTF text and attempts
/// to append it as RTF to the content of the control.
/// </summary>
/// <param name="_rtf"></param>
public void AppendRtf(string _rtf)
{
// Move caret to the end of the text
this.Select(this.TextLength, 0);
// Since SelectedRtf is null, this will append the string to the
// end of the existing RTF
this.SelectedRtf = _rtf;
}
/// <summary>
/// Assumes that the string passed as a parameter is valid RTF text and
/// attempts to insert it as RTF into the content of the control.
/// </summary>
/// <remarks>
/// NOTE: The text is inserted wherever the caret is at the time of the call,
/// and if any text is selected, that text is replaced.
/// </remarks>
/// <param name="_rtf"></param>
public void InsertRtf(string _rtf)
{
this.SelectedRtf = _rtf;
}
/// <summary>
/// Appends the text using the current font, text, and highlight colors.
/// </summary>
/// <param name="_text"></param>
public void AppendTextAsRtf(string _text)
{
AppendTextAsRtf(_text, this.Font);
}
/// <summary>
/// Appends the text using the given font, and current text and highlight
/// colors.
/// </summary>
/// <param name="_text"></param>
/// <param name="_font"></param>
public void AppendTextAsRtf(string _text, Font _font)
{
AppendTextAsRtf(_text, _font, textColor);
}
/// <summary>
/// Appends the text using the given font and text color, and the current
/// highlight color.
/// </summary>
/// <param name="_text"></param>
/// <param name="_font"></param>
/// <param name="_color"></param>
public void AppendTextAsRtf(string _text, Font _font, RtfColor _textColor)
{
AppendTextAsRtf(_text, _font, _textColor, highlightColor);
}
/// <summary>
/// Appends the text using the given font, text, and highlight colors. Simply
/// moves the caret to the end of the RichTextBox's text and makes a call to
/// insert.
/// </summary>
/// <param name="_text"></param>
/// <param name="_font"></param>
/// <param name="_textColor"></param>
/// <param name="_backColor"></param>
public void AppendTextAsRtf(string _text, Font _font, RtfColor _textColor, RtfColor _backColor)
{
// Move carret to the end of the text
this.Select(this.TextLength, 0);
InsertTextAsRtf(_text, _font, _textColor, _backColor);
}
#endregion
#region Insert Plain Text
/// <summary>
/// Inserts the text using the current font, text, and highlight colors.
/// </summary>
/// <param name="_text"></param>
public void InsertTextAsRtf(string _text)
{
InsertTextAsRtf(_text, this.Font);
}
/// <summary>
/// Inserts the text using the given font, and current text and highlight
/// colors.
/// </summary>
/// <param name="_text"></param>
/// <param name="_font"></param>
public void InsertTextAsRtf(string _text, Font _font)
{
InsertTextAsRtf(_text, _font, textColor);
}
/// <summary>
/// Inserts the text using the given font and text color, and the current
/// highlight color.
/// </summary>
/// <param name="_text"></param>
/// <param name="_font"></param>
/// <param name="_color"></param>
public void InsertTextAsRtf(string _text, Font _font, RtfColor _textColor)
{
InsertTextAsRtf(_text, _font, _textColor, highlightColor);
}
/// <summary>
/// Inserts the text using the given font, text, and highlight colors. The
/// text is wrapped in RTF codes so that the specified formatting is kept.
/// You can only assign valid RTF to the RichTextBox.Rtf property, else
/// an exception is thrown. The RTF string should follow this format ...
///
/// {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{[FONTS]}{\colortbl ;[COLORS]}}
/// \viewkind4\uc1\pard\cf1\f0\fs20 [DOCUMENT AREA] }
///
/// </summary>
/// <remarks>
/// NOTE: The text is inserted wherever the caret is at the time of the call,
/// and if any text is selected, that text is replaced.
/// </remarks>
/// <param name="_text"></param>
/// <param name="_font"></param>
/// <param name="_color"></param>
/// <param name="_color"></param>
public void InsertTextAsRtf(string _text, Font _font, RtfColor _textColor, RtfColor _backColor)
{
StringBuilder _rtf = new StringBuilder();
// Append the RTF header
_rtf.Append(RTF_HEADER);
// Create the font table from the font passed in and append it to the
// RTF string
_rtf.Append(GetFontTable(_font));
// Create the color table from the colors passed in and append it to the
// RTF string
_rtf.Append(GetColorTable(_textColor, _backColor));
// Create the document area from the text to be added as RTF and append
// it to the RTF string.
_rtf.Append(GetDocumentArea(_text, _font));
this.SelectedRtf = _rtf.ToString();
}
/// <summary>
/// Creates the Document Area of the RTF being inserted. The document area
/// (in this case) consists of the text being added as RTF and all the
/// formatting specified in the Font object passed in. This should have the
/// form ...
///
/// \viewkind4\uc1\pard\cf1\f0\fs20 [DOCUMENT AREA] }
///
/// </summary>
/// <param name="_text"></param>
/// <param name="_font"></param>
/// <returns>
/// The document area as a string.
/// </returns>
private string GetDocumentArea(string _text, Font _font)
{
StringBuilder _doc = new StringBuilder();
// Append the standard RTF document area control string
_doc.Append(RTF_DOCUMENT_PRE);
// Set the highlight color (the color behind the text) to the
// third color in the color table. See GetColorTable for more details.
_doc.Append(@"\highlight2");
// If the font is bold, attach corresponding tag
if (_font.Bold)
_doc.Append(@"\b");
// If the font is italic, attach corresponding tag
if (_font.Italic)
_doc.Append(@"\i");
// If the font is strikeout, attach corresponding tag
if (_font.Strikeout)
_doc.Append(@"\strike");
// If the font is underlined, attach corresponding tag
if (_font.Underline)
_doc.Append(@"\ul");
// Set the font to the first font in the font table.
// See GetFontTable for more details.
_doc.Append(@"\f0");
// Set the size of the font. In RTF, font size is measured in
// half-points, so the font size is twice the value obtained from
// Font.SizeInPoints
_doc.Append(@"\fs");
_doc.Append((int)Math.Round((2 * _font.SizeInPoints)));
// Apppend a space before starting actual text (for clarity)
_doc.Append(@" ");
// Append actual text, however, replace newlines with RTF \par.
// Any other special text should be handled here (e.g.) tabs, etc.
_doc.Append(_text.Replace("\n", @"\par "));
// RTF isn't strict when it comes to closing control words, but what the
// heck ...
// Remove the highlight
_doc.Append(@"\highlight0");
// If font is bold, close tag
if (_font.Bold)
_doc.Append(@"\b0");
// If font is italic, close tag
if (_font.Italic)
_doc.Append(@"\i0");
// If font is strikeout, close tag
if (_font.Strikeout)
_doc.Append(@"\strike0");
// If font is underlined, cloes tag
if (_font.Underline)
_doc.Append(@"\ulnone");
// Revert back to default font and size
_doc.Append(@"\f0");
_doc.Append(@"\fs20");
// Close the document area control string
_doc.Append(RTF_DOCUMENT_POST);
return _doc.ToString();
}
#endregion
#region Insert Image
/// <summary>
/// Inserts an image into the RichTextBox. The image is wrapped in a Windows
/// Format Metafile, because although Microsoft discourages the use of a WMF,
/// the RichTextBox (and even MS Word), wraps an image in a WMF before inserting
/// the image into a document. The WMF is attached in HEX format (a string of
/// HEX numbers).
///
/// The RTF Specification v1.6 says that you should be able to insert bitmaps,
/// .jpegs, .gifs, .pngs, and Enhanced Metafiles (.emf) directly into an RTF
/// document without the WMF wrapper. This works fine with MS Word,
/// however, when you don't wrap images in a WMF, WordPad and
/// RichTextBoxes simply ignore them. Both use the riched20.dll or msfted.dll.
/// </summary>
/// <remarks>
/// NOTE: The image is inserted wherever the caret is at the time of the call,
/// and if any text is selected, that text is replaced.
/// </remarks>
/// <param name="_image"></param>
public void InsertImage(Image _image)
{
StringBuilder _rtf = new StringBuilder();
// Append the RTF header
_rtf.Append(RTF_HEADER);
// Create the font table using the RichTextBox's current font and append
// it to the RTF string
_rtf.Append(GetFontTable(this.Font));
// Create the image control string and append it to the RTF string
_rtf.Append(GetImagePrefix(_image));
// Create the Windows Metafile and append its bytes in HEX format
_rtf.Append(GetRtfImage(_image));
// Close the RTF image control string
_rtf.Append(RTF_IMAGE_POST);
this.SelectedRtf = _rtf.ToString();
}
/// <summary>
/// Creates the RTF control string that describes the image being inserted.
/// This description (in this case) specifies that the image is an
/// MM_ANISOTROPIC metafile, meaning that both X and Y axes can be scaled
/// independently. The control string also gives the images current dimensions,
/// and its target dimensions, so if you want to control the size of the
/// image being inserted, this would be the place to do it. The prefix should
/// have the form ...
///
/// {\pict\wmetafile8\picw[A]\pich[B]\picwgoal[C]\pichgoal[D]
///
/// where ...
///
/// A = current width of the metafile in hundredths of millimeters (0.01mm)
/// = Image Width in Inches * Number of (0.01mm) per inch
/// = (Image Width in Pixels / Graphics Context's Horizontal Resolution) * 2540
/// = (Image Width in Pixels / Graphics.DpiX) * 2540
///
/// B = current height of the metafile in hundredths of millimeters (0.01mm)
/// = Image Height in Inches * Number of (0.01mm) per inch
/// = (Image Height in Pixels / Graphics Context's Vertical Resolution) * 2540
/// = (Image Height in Pixels / Graphics.DpiX) * 2540
///
/// C = target width of the metafile in twips
/// = Image Width in Inches * Number of twips per inch
/// = (Image Width in Pixels / Graphics Context's Horizontal Resolution) * 1440
/// = (Image Width in Pixels / Graphics.DpiX) * 1440
///
/// D = target height of the metafile in twips
/// = Image Height in Inches * Number of twips per inch
/// = (Image Height in Pixels / Graphics Context's Horizontal Resolution) * 1440
/// = (Image Height in Pixels / Graphics.DpiX) * 1440
///
/// </summary>
/// <remarks>
/// The Graphics Context's resolution is simply the current resolution at which
/// windows is being displayed. Normally it's 96 dpi, but instead of assuming
/// I just added the code.
///
/// According to Ken Howe at pbdr.com, "Twips are screen-independent units
/// used to ensure that the placement and proportion of screen elements in
/// your screen application are the same on all display systems."
///
/// Units Used
/// ----------
/// 1 Twip = 1/20 Point
/// 1 Point = 1/72 Inch
/// 1 Twip = 1/1440 Inch
///
/// 1 Inch = 2.54 cm
///
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -