namespace Khendys.Controls {
#region Public Enums
// Enum for possible RTF colors public enum RtfColor { Black, Maroon, Green, Olive, Navy, Purple, Teal, Gray, Silver, Red, Lime, Yellow, Blue, Fuchsia, Aqua, White }
#endregion
public class ExRichTextBox : System.Windows.Forms.RichTextBox {
#region My Enums
// Specifies the flags/options for the unmanaged call to the GDI+ method // Metafile.EmfToWmfBits(). private enum EmfToWmfBitsFlags {
// Use the default conversion EmfToWmfBitsFlagsDefault = 0x00000000,
// Embedded the source of the EMF metafiel within the resulting WMF // metafile EmfToWmfBitsFlagsEmbedEmf = 0x00000001,
// Place a 22-byte header in the resulting WMF file. The header is // required for the metafile to be considered placeable. EmfToWmfBitsFlagsIncludePlaceable = 0x00000002,
// Don't simulate clipping by using the XOR operator. EmfToWmfBitsFlagsNoXORClip = 0x00000004 };
#endregion
#region My Structs
// Definitions for colors in an RTF document private struct RtfColorDef { public const string Black = @"\red0\green0\blue0"; public const string Maroon = @"\red128\green0\blue0"; public const string Green = @"\red0\green128\blue0"; public const string Olive = @"\red128\green128\blue0"; public const string Navy = @"\red0\green0\blue128"; public const string Purple = @"\red128\green0\blue128"; public const string Teal = @"\red0\green128\blue128"; public const string Gray = @"\red128\green128\blue128"; public const string Silver = @"\red192\green192\blue192"; public const string Red = @"\red255\green0\blue0"; public const string Lime = @"\red0\green255\blue0"; public const string Yellow = @"\red255\green255\blue0"; public const string Blue = @"\red0\green0\blue255"; public const string Fuchsia = @"\red255\green0\blue255"; public const string Aqua = @"\red0\green255\blue255"; public const string White = @"\red255\green255\blue255"; }
// Control words for RTF font families private struct RtfFontFamilyDef { public const string Unknown = @"\fnil"; public const string Roman = @"\froman"; public const string Swiss = @"\fswiss"; public const string Modern = @"\fmodern"; public const string Script = @"\fscript"; public const string Decor = @"\fdecor"; public const string Technical = @"\ftech"; public const string BiDirect = @"\fbidi"; }
#endregion
#region My Constants
// Not used in this application. Descriptions can be found with documentation // of Windows GDI function SetMapMode private const int MM_TEXT = 1; private const int MM_LOMETRIC = 2; private const int MM_HIMETRIC = 3; private const int MM_LOENGLISH = 4; private const int MM_HIENGLISH = 5; private const int MM_TWIPS = 6;
// Ensures that the metafile maintains a 1:1 aspect ratio private const int MM_ISOTROPIC = 7;
// Allows the x-coordinates and y-coordinates of the metafile to be adjusted // independently private const int MM_ANISOTROPIC = 8;
// Represents an unknown font family private const string FF_UNKNOWN = "UNKNOWN";
// The number of hundredths of millimeters (0.01 mm) in an inch // For more information, see GetImagePrefix() method. private const int HMM_PER_INCH = 2540;
// The number of twips in an inch // For more information, see GetImagePrefix() method. private const int TWIPS_PER_INCH = 1440;
#endregion
#region My Privates
// The default text color private RtfColor textColor;
// The default text background color private RtfColor highlightColor;
// Dictionary that maps color enums to RTF color codes private HybridDictionary rtfColor;
// Dictionary that mapas Framework font families to RTF font families private HybridDictionary rtfFontFamily;
// The horizontal resolution at which the control is being displayed private float xDpi;
// The vertical resolution at which the control is being displayed private float yDpi;
#endregion
#region Elements required to create an RTF document /* RTF HEADER * ---------- * * \rtf[N] - For text to be considered to be RTF, it must be enclosed in this tag. * rtf1 is used because the RichTextBox conforms to RTF Specification * version 1. * \ansi - The character set. * \ansicpg[N] - Specifies that unicode characters might be embedded. ansicpg1252 * is the default used by Windows. * \deff[N] - The default font. \deff0 means the default font is the first font * found. * \deflang[N] - The default language. \deflang1033 specifies US English. * */ private const string RTF_HEADER = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033";
/* RTF DOCUMENT AREA * ----------------- * * \viewkind[N] - The type of view or zoom level. \viewkind4 specifies normal view. * \uc[N] - The number of bytes corresponding to a Unicode character. * \pard - Resets to default paragraph properties * \cf[N] - Foreground color. \cf1 refers to the color at index 1 in * the color table * \f[N] - Font number. \f0 refers to the font at index 0 in the font * table. * \fs[N] - Font size in half-points. * */ private const string RTF_DOCUMENT_PRE = @"\viewkind4\uc1\pard\cf1\f0\fs20"; private const string RTF_DOCUMENT_POST = @"\cf0\fs17}"; private string RTF_IMAGE_POST = @"}";
#endregion
#region Accessors
// TOD 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 ExRichTextBox() : 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 ExRichTextBox(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 ExRichTextBox(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); }