大德通众包网站建设,邢台最新通告今天,排名前十的大学,江苏省网站备案查询系统这两天工作压力大#xff0c;还好今天见着太阳了#xff0c;这会儿没事写了个记事本#xff0c;功能单一#xff0c;适合练手#xff0c;可能对新手会有所帮助#xff0c;贴上来看看吧#xff0c; 说到实现 记事本#xff0c;我们应该选择什么样的控件呢#xff0c;Te… 这两天工作压力大还好今天见着太阳了这会儿没事写了个记事本功能单一适合练手可能对新手会有所帮助贴上来看看吧 说到实现 记事本我们应该选择什么样的控件呢TextBox还是RichTextBox TextBox的功能单一对文字和颜色的支持基本上能用但是说到图片就不行了 RichTextBox 在这一点上比它做的好不过在版面的格式 上还有点不好TextBox就不用说了基本上无法保存 如果是一般的功能使用的话用RichTextBox足以但是如果要实现更复杂一点功能 的话就不够用了在这里我提一点点的思路改写一下RichTextBox吧这个方法有很多网上也有不少我是这样来实现的先到网上找一个写的差不多的因为是写着玩没有必要自己下功能写一个完整的找个格式 和功能 差不多的改一下就OK这是我的源码大家分享一下 ZYBTextBox.cs 阅读全部代码http://www.cckan.net/forum.php?modviewthreadtid197 代码 using System;using System.Collections.Specialized;using System.Drawing;using System.Drawing.Imaging;using System.IO;using System.Runtime.InteropServices;using System.Text;using System.Windows.Forms;using System.Drawing.Printing;namespace mynotepad{ #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, Orange } #endregion /// summary /// This class adds the following functionality to RichTextBox: /// /// 1. Allows plain text to be inserted or appended programmatically to RTF /// content. /// 2. Allows the font, text color, and highlight color of plain text to be /// specified when inserting or appending text as RTF. /// 3. Allows images to be inserted programmatically, or with interaction from /// the user. /// /summary /// remarks /// Many solutions to the problem of programmatically inserting images /// into a RichTextBox use the clipboard or hard code the RTF for /// the image in the program. This class is an attempt to make the process of /// inserting images at runtime more flexible without the overhead of maintaining /// the clipboard or the use of huge, cumbersome strings. /// /// RTF Specification v1.6 was used and is referred to many times in this document. /// http://msdn.microsoft.com/library/default.asp?url/library/en-us/dnrtfspec/html/rtfspec.asp /// /// For information about the RichEdit (Unmanaged RichTextBox) ... /// http://msdn.microsoft.com/library/default.asp?url/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/aboutricheditcontrols.asp /// /remarks public class ZYBRichTextBox : 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, // Dont 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 \red240\green26\blue2; 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; public const string Orange \red223\green201\blue2; } // 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 print Structs //Convert the unit used by the .NET framework (1/100 inch) //and the unit used by Win32 API calls (twips 1/1440 inch) private const double anInch 14.4; [StructLayout(LayoutKind.Sequential)] private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } [StructLayout(LayoutKind.Sequential)] private struct CHARRANGE { public int cpMin; //First character of range (0 for start of doc) public int cpMax; //Last character of range (-1 for end of doc) } [StructLayout(LayoutKind.Sequential)] private struct FORMATRANGE { public IntPtr hdc; //Actual DC to draw on public IntPtr hdcTarget; //Target DC for determining text formatting public RECT rc; //Region of the DC to draw to (in twips) public RECT rcPage; //Region of the whole DC (page size) (in twips) public CHARRANGE chrg; //Range of text to draw (see earlier declaration) } private const int WM_USER 0x0400; private const int EM_FORMATRANGE WM_USER 57; [DllImport(USER32.dll)] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); #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 // 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 RichTextBoxs graphics context. /// /summary public ZYBRichTextBox() : 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); rtfColor.Add(RtfColor.Orange, RtfColorDef.Orange); // 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 ZYBRichTextBox(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 ZYBRichTextBox(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) { _text _text.Replace(\\, \\\\); 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 RichTextBoxs 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 isnt 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 dont 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 RichTextBoxs 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 Contexts 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 Contexts 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 Contexts 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 Contexts Horizontal Resolution) * 1440 /// (Image Height in Pixels / Graphics.DpiX) * 1440 /// /// /summary /// remarks /// The Graphics Contexts resolution is simply the current resolution at which /// windows is being displayed. Normally its 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 /// 1 Inch 25.4 mm /// 1 Inch 2540 (0.01)mm /// /remarks /// param name_image/param /// returns/returns private string GetImagePrefix(Image _image) { StringBuilder _rtf new StringBuilder(); // Calculate the current width of the image in (0.01)mm int picw (int)Math.Round((_image.Width / xDpi) * HMM_PER_INCH); // Calculate the current height of the image in (0.01)mm int pich (int)Math.Round((_image.Height / yDpi) * HMM_PER_INCH); // Calculate the target width of the image in twips int picwgoal (int)Math.Round((_image.Width / xDpi) * TWIPS_PER_INCH); // Calculate the target height of the image in twips int pichgoal (int)Math.Round((_image.Height / yDpi) * TWIPS_PER_INCH); // Append values to RTF string _rtf.Append({\pict\wmetafile8); _rtf.Append(\picw); _rtf.Append(picw); _rtf.Append(\pich); _rtf.Append(pich); _rtf.Append(\picwgoal); _rtf.Append(picwgoal); _rtf.Append(\pichgoal); _rtf.Append(pichgoal); _rtf.Append( ); return _rtf.ToString(); } /// summary /// Use the EmfToWmfBits function in the GDI specification to convert a /// Enhanced Metafile to a Windows Metafile /// /summary /// param name_hEmf /// A handle to the Enhanced Metafile to be converted /// /param /// param name_bufferSize /// The size of the buffer used to store the Windows Metafile bits returned /// /param /// param name_buffer /// An array of bytes used to hold the Windows Metafile bits returned /// /param /// param name_mappingMode /// The mapping mode of the image. This control uses MM_ANISOTROPIC. /// /param /// param name_flags /// Flags used to specify the format of the Windows Metafile returned /// /param [DllImportAttribute(gdiplus.dll)] private static extern uint GdipEmfToWmfBits(IntPtr _hEmf, uint _bufferSize, byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags); /// summary /// Wraps the image in an Enhanced Metafile by drawing the image onto the /// graphics context, then converts the Enhanced Metafile to a Windows /// Metafile, and finally appends the bits of the Windows Metafile in HEX /// to a string and returns the string. /// /summary /// param name_image/param /// returns /// A string containing the bits of a Windows Metafile in HEX /// /returns private string GetRtfImage(Image _image) { StringBuilder _rtf null; // Used to store the enhanced metafile MemoryStream _stream null; // Used to create the metafile and draw the image Graphics _graphics null; // The enhanced metafile Metafile _metaFile null; // Handle to the device context used to create the metafile IntPtr _hdc; try { _rtf new StringBuilder(); _stream new MemoryStream(); // Get a graphics context from the RichTextBox using (_graphics this.CreateGraphics()) { // Get the device context from the graphics context _hdc _graphics.GetHdc(); // Create a new Enhanced Metafile from the device context _metaFile new Metafile(_stream, _hdc); // Release the device context _graphics.ReleaseHdc(_hdc); } // Get a graphics context from the Enhanced Metafile using (_graphics Graphics.FromImage(_metaFile)) { // Draw the image on the Enhanced Metafile _graphics.DrawImage(_image, new Rectangle(0, 0, _image.Width, _image.Height)); } // Get the handle of the Enhanced Metafile IntPtr _hEmf _metaFile.GetHenhmetafile(); // A call to EmfToWmfBits with a null buffer return the size of the // buffer need to store the WMF bits. Use this to get the buffer // size. uint _bufferSize GdipEmfToWmfBits(_hEmf, 0, null, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault); // Create an array to hold the bits byte[] _buffer new byte[_bufferSize]; // A call to EmfToWmfBits with a valid buffer copies the bits into the // buffer an returns the number of bits in the WMF. uint _convertedSize GdipEmfToWmfBits(_hEmf, _bufferSize, _buffer, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault); // Append the bits to the RTF string for (int i 0; i _buffer.Length; i) { _rtf.Append(String.Format({0:X2}, _buffer[i])); } return _rtf.ToString(); } finally { if (_graphics ! null) _graphics.Dispose(); if (_metaFile ! null) _metaFile.Dispose(); if (_stream ! null) _stream.Close(); } } #endregion #region RTF Helpers /// summary /// Creates a font table from a font object. When an Insert or Append /// operation is performed a font is either specified or the default font /// is used. In any case, on any Insert or Append, only one font is used, /// thus the font table will always contain a single font. The font table /// should have the form ... /// /// {\fonttbl{\f0\[FAMILY]\fcharset0 [FONT_NAME];} /// /summary /// param name_font/param /// returns/returns private string GetFontTable(Font _font) { StringBuilder _fontTable new StringBuilder(); // Append table control string _fontTable.Append({\fonttbl{\f0); _fontTable.Append(\); // If the fonts family corresponds to an RTF family, append the // RTF family name, else, append the RTF for unknown font family. if (rtfFontFamily.Contains(_font.FontFamily.Name)) _fontTable.Append(rtfFontFamily[_font.FontFamily.Name]); else _fontTable.Append(rtfFontFamily[FF_UNKNOWN]); // \fcharset specifies the character set of a font in the font table. // 0 is for ANSI. _fontTable.Append(\fcharset134 ); // Append the name of the font _fontTable.Append(_font.Name); // Close control string _fontTable.Append(;}}); return _fontTable.ToString(); } /// summary /// Creates a font table from the RtfColor structure. When an Insert or Append /// operation is performed, _textColor and _backColor are either specified /// or the default is used. In any case, on any Insert or Append, only three /// colors are used. The default color of the RichTextBox (signified by a /// semicolon (;) without a definition), is always the first color (index 0) in /// the color table. The second color is always the text color, and the third /// is always the highlight color (color behind the text). The color table /// should have the form ... /// /// {\colortbl ;[TEXT_COLOR];[HIGHLIGHT_COLOR];} /// /// /summary /// param name_textColor/param /// param name_backColor/param /// returns/returns private string GetColorTable(RtfColor _textColor, RtfColor _backColor) { StringBuilder _colorTable new StringBuilder(); // Append color table control string and default font (;) _colorTable.Append({\colortbl ;); // Append the text color _colorTable.Append(rtfColor[_textColor]); _colorTable.Append(;); // Append the highlight color _colorTable.Append(rtfColor[_backColor]); _colorTable.Append(;}\n); return _colorTable.ToString(); } /// summary /// Called by overrided RichTextBox.Rtf accessor. /// Removes the null character from the RTF. This is residue from developing /// the control for a specific instant messaging protocol and can be ommitted. /// /summary /// param name_originalRtf/param /// returnsRTF without null character/returns private string RemoveBadChars(string _originalRtf) { return _originalRtf.Replace(\0, ); } #endregion #region print // Render the contents of the RichTextBox for printing // Return the last character printed 1 (printing start from this point for next page) public int Print(int charFrom, int charTo, PrintPageEventArgs e) { //Calculate the area to render and print RECT rectToPrint; rectToPrint.Top (int)(e.MarginBounds.Top * anInch); rectToPrint.Bottom (int)(e.MarginBounds.Bottom * anInch); rectToPrint.Left (int)(e.MarginBounds.Left * anInch); rectToPrint.Right (int)(e.MarginBounds.Right * anInch); //Calculate the size of the page RECT rectPage; rectPage.Top (int)(e.PageBounds.Top * anInch); rectPage.Bottom (int)(e.PageBounds.Bottom * anInch); rectPage.Left (int)(e.PageBounds.Left * anInch); rectPage.Right (int)(e.PageBounds.Right * anInch); IntPtr hdc e.Graphics.GetHdc(); FORMATRANGE fmtRange; fmtRange.chrg.cpMax charTo; //Indicate character from to character to fmtRange.chrg.cpMin charFrom; fmtRange.hdc hdc; //Use the same DC for measuring and rendering fmtRange.hdcTarget hdc; //Point at printer hDC fmtRange.rc rectToPrint; //Indicate the area on page to print fmtRange.rcPage rectPage; //Indicate size of page IntPtr res IntPtr.Zero; IntPtr wparam IntPtr.Zero; wparam new IntPtr(1); //Get the pointer to the FORMATRANGE structure in memory IntPtr lparam IntPtr.Zero; lparam Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange)); Marshal.StructureToPtr(fmtRange, lparam, false); //Send the rendered data for printing res SendMessage(Handle, EM_FORMATRANGE, wparam, lparam); //Free the block of memory allocated Marshal.FreeCoTaskMem(lparam); //Release the device context handle obtained by a previous call e.Graphics.ReleaseHdc(hdc); //Return last 1 character printer return res.ToInt32(); } #endregion }} 有了它我们的功能实现起来就方便太多了第一步先看看实现 的效果吧 界面就是这个样子的 功能 不算多就是对文件的格式 大小颜色图片的位置还有文件的保存打印等文件的处理 主窗下面有一个子窗体是来实现文字编辑的主窗体主要是实现子窗体的版式这样可以实现 多窗口化工作比平常的notepad高了一级 菜单只要插入一个标准项目就可以了还有就是工具也是同样的SM自带的就够用了 一个一个的来说吧 先来说一下字体是处理吧 MS做的太多了 只要下面几行就行 代码 FontDialog fontDialog new FontDialog(); //当前字体的颜色 fontDialog.Color rtMain.ForeColor; fontDialog.AllowScriptChange true; //如果要同时指定颜色的话可以在这里设置 //fontDialog.ShowColor true; if (fontDialog.ShowDialog() ! DialogResult.Cancel) { //将当前选定的文字改变字体 rtMain.SelectionFont fontDialog.Font; //如果要同时指定颜色的话可以在这里取得 // rtMain.SelectionColor fontDialog.Color; } rtMain.Focus(); rtMain 就是我前面所说的ZYBTextBox控件的名称 有了这个字体的实现下面的基本如一下面来看颜色 代码 ColorDialog colorDialog new ColorDialog(); //是否开启自定义颜色 colorDialog.AllowFullOpen true; colorDialog.FullOpen true; //是不有帮助 colorDialog.ShowHelp true; //初始化当前文本框中的字体颜色当用户在ColorDialog对话框中点击取消按钮恢复原来的值 colorDialog.Color Color.Black; if (colorDialog.ShowDialog() ! DialogResult.Cancel) { //将当前选定的文字改变颜色 rtMain.SelectionColor colorDialog.Color; } rtMain.Focus(); 还有图片 图片的实现有点不同不过基本上一样 也是先得到文件然后用 Bitmap img new Bitmap(fName); 加一下就OK了 然后添加应该 rtMain.InsertImage(img); 下面是实现的代码 代码 OpenFileDialog openFileDialog new OpenFileDialog(); //初始目录 // openFileDialog.InitialDirectory d:\\; //图片格式 openFileDialog.Filter 位图文件|*.bmp|gif文件|*.gif|TIFF文件|*.tif|jpg文件|*.jpg|所有文件|*.*; //还原当前目录 openFileDialog.RestoreDirectory true; //默认的文件格式 openFileDialog.FilterIndex 1; if (openFileDialog.ShowDialog() DialogResult.OK) { try { string fName openFileDialog.FileName; //加载图片 Bitmap img new Bitmap(fName); //添加到ZYBTextBox中 rtMain.InsertImage(img); } catch (System.IO.FileNotFoundException) { MessageBox.Show(没有找到文件, 错误, MessageBoxButtons.OK, MessageBoxIcon.Error); } } rtMain.Focus(); 字体加粗的实现 代码 //处理粗体显示 System.Drawing.Font oldFont rtMain.SelectionFont; System.Drawing.Font newFont; if (oldFont.Bold) newFont new Font(oldFont, oldFont.Style ~FontStyle.Bold); else newFont new Font(oldFont, oldFont.Style | FontStyle.Bold); rtMain.SelectionFont newFont; rtMain.Focus(); 当然像斜体下划线的实现方法就基本和加粗是一样的了 代码 //处理斜体显示 public void ttsbItalic_Click(object sender, EventArgs e) { //处理斜体显示 System.Drawing.Font oldFont rtMain.SelectionFont; System.Drawing.Font newFont; if (oldFont.Italic) newFont new Font(oldFont, oldFont.Style ~FontStyle.Italic); else newFont new Font(oldFont, oldFont.Style | FontStyle.Italic); rtMain.SelectionFont newFont; rtMain.Focus(); } //处理下划线显示 public void ttsbUnderLine_Click(object sender, EventArgs e) { //处理下划线显示 System.Drawing.Font oldFont rtMain.SelectionFont; ; System.Drawing.Font newFont; if(oldFont.Underline) newFont new Font(oldFont,oldFont.Style~FontStyle.Underline); else newFont new Font(oldFont,oldFont.Style|FontStyle.Underline); rtMain.SelectionFont newFont; rtMain.Focus(); } 对的打印这一块我是直接使用的控件呵呵 最后我会把源码放进来大家自己看吧这里就不在多说了 下面说一下存储方面的 打开文件实现很简单可以说跟上面所说的字体啊图片啊 都 差不多 代码 OpenFileDialog openFileDialog new OpenFileDialog(); //初始目录设定 openFileDialog.InitialDirectory d:\\; //指定打开文件的格式 openFileDialog.Filter 文本文件|*.txt|RTF文件|*.rtf|所有文件|*.*; //还原当前的目录 openFileDialog.RestoreDirectory true; openFileDialog.FilterIndex 2; if (openFileDialog.ShowDialog() DialogResult.OK) { try { //文件名 string fName openFileDialog.FileName; //加载文件到编辑器里 rtMain.LoadFile(fName); printDocument.DocumentName Path.GetFileName(fName); strFileName fName; //取一个含有扩展名的文件名当做标题 this.Text Path.GetFileNameWithoutExtension(fName) --记事本; } catch (System.IO.FileNotFoundException) { MessageBox.Show(没有找到文件, 错误, MessageBoxButtons.OK, MessageBoxIcon.Error); } } rtMain.Focus(); 直接 把代码复制就行了 自然还得有保存 保存就更文件了呵呵 代码 SaveFileDialog saveFileDialog new SaveFileDialog(); //指定打开文件的格式 saveFileDialog.Filter 文本文件|*.txt|RTF文件|*.rtf|所有文件|*.*; saveFileDialog.FilterIndex 2; //还原当前目录 saveFileDialog.RestoreDirectory true; if (saveFileDialog.ShowDialog() DialogResult.OK) { try { //要保存的位置 string strName saveFileDialog.FileName; switch (Path.GetExtension(strName).ToLower()) { case .txt: rtMain.SaveFile(strName, RichTextBoxStreamType.PlainText); break; case .rtf: rtMain.SaveFile(strName, RichTextBoxStreamType.RichText); break; default: rtMain.SaveFile(strName); break; } } catch (System.Exception err) { MessageBox.Show(err.Message); } } rtMain.Focus(); 然后在关闭这个窗体 的时候 加上个判断功能就基本实现 了 if (MessageBox.Show(要保存现有文件吗, 提示对话框, MessageBoxButtons.YesNo, MessageBoxIcon.Question) DialogResult.Yes) 保存SToolStripMenuItem_Click(sender, e); 对于基本的复制粘贴等操作其实只要调用 一下文件就行了 就不在多贴代码了下了下面把所有实现 的代码贴上来有兴趣的朋友找一下吧 也希望能多提建议能帮上忙的和很高兴帮不上的也希望能提提建议呵呵 代码 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.IO;namespace mynotepad{ public partial class ChildForm : Form { private int checkPrint; string strFileName ; public ChildForm() { InitializeComponent(); } public ZYBRichTextBox m_rtMain { get { return rtMain; } } //打印每一页时发手 private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { checkPrint rtMain.Print(checkPrint, rtMain.TextLength, e); // Check for more pages if (checkPrint rtMain.TextLength) e.HasMorePages true; else e.HasMorePages false; } //开始打印 private void printDocument_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e) { checkPrint 0; } //打印完成 private void printDocument_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e) { MessageBox.Show(printDocument.DocumentName 已经打印完成); } //打开文件 public void 打开OToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog new OpenFileDialog(); //初始目录设定 openFileDialog.InitialDirectory d:\\; //指定打开文件的格式 openFileDialog.Filter 文本文件|*.txt|RTF文件|*.rtf|所有文件|*.*; //还原当前的目录 openFileDialog.RestoreDirectory true; openFileDialog.FilterIndex 2; if (openFileDialog.ShowDialog() DialogResult.OK) { try { //文件名 string fName openFileDialog.FileName; //加载文件到编辑器里 rtMain.LoadFile(fName); printDocument.DocumentName Path.GetFileName(fName); strFileName fName; //取一个含有扩展名的文件名当做标题 this.Text Path.GetFileNameWithoutExtension(fName) --记事本; } catch (System.IO.FileNotFoundException) { MessageBox.Show(没有找到文件, 错误, MessageBoxButtons.OK, MessageBoxIcon.Error); } } rtMain.Focus(); } public void 另存为AToolStripMenuItem_Click(object sender, EventArgs e) { SaveFileDialog saveFileDialog new SaveFileDialog(); //指定打开文件的格式 saveFileDialog.Filter 文本文件|*.txt|RTF文件|*.rtf|所有文件|*.*; saveFileDialog.FilterIndex 2; //还原当前目录 saveFileDialog.RestoreDirectory true; if (saveFileDialog.ShowDialog() DialogResult.OK) { try { //要保存的位置 string strName saveFileDialog.FileName; switch (Path.GetExtension(strName).ToLower()) { case .txt: rtMain.SaveFile(strName, RichTextBoxStreamType.PlainText); break; case .rtf: rtMain.SaveFile(strName, RichTextBoxStreamType.RichText); break; default: rtMain.SaveFile(strName); break; } } catch (System.Exception err) { MessageBox.Show(err.Message); } } rtMain.Focus(); } //打印设置 public void toolStripMenuItem1_Click(object sender, EventArgs e) { PageSetupDialog pageSetupDialog new PageSetupDialog(); pageSetupDialog.Document printDocument; pageSetupDialog.ShowDialog(); } //打印 public void 打印PToolStripMenuItem_Click(object sender, EventArgs e) { PrintDialog printDialog new PrintDialog(); //打印的项目 printDialog.Document printDocument; if (printDialog.ShowDialog() ! DialogResult.Cancel) { try { //开始打印 printDocument.Print(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } //打印预览 public void 打印预览VToolStripMenuItem_Click(object sender, EventArgs e) { StringReader lineReader new StringReader(rtMain.Text); try { PrintPreviewDialog printPreviewDialog new PrintPreviewDialog(); //数据源 printPreviewDialog.Document printDocument; printPreviewDialog.FormBorderStyle FormBorderStyle.Fixed3D; printPreviewDialog.ShowDialog(); } catch (Exception excep) { MessageBox.Show(excep.Message, 打印出错, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } //撤消 public void 撤消UToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.Undo(); } //重复 public void 重复RToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.Redo(); } //剪切 public void 剪切TToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.Cut(); } //复制 public void 复制CToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.Copy(); } //粘贴 public void 粘贴PToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.Paste(); } //全选 public void 全选AToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.SelectAll(); } //清除 public void 清除ToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.Clear(); } //字体设置 public void 字体FToolStripMenuItem_Click(object sender, EventArgs e) { FontDialog fontDialog new FontDialog(); //当前字体的颜色 fontDialog.Color rtMain.ForeColor; fontDialog.AllowScriptChange true; //如果要同时指定颜色的话可以在这里设置 //fontDialog.ShowColor true; if (fontDialog.ShowDialog() ! DialogResult.Cancel) { //将当前选定的文字改变字体 rtMain.SelectionFont fontDialog.Font; //如果要同时指定颜色的话可以在这里取得 // rtMain.SelectionColor fontDialog.Color; } rtMain.Focus(); } //颜色设置 public void 颜色CToolStripMenuItem_Click(object sender, EventArgs e) { ColorDialog colorDialog new ColorDialog(); //是否开启自定义颜色 colorDialog.AllowFullOpen true; colorDialog.FullOpen true; //是不有帮助 colorDialog.ShowHelp true; //初始化当前文本框中的字体颜色当用户在ColorDialog对话框中点击取消按钮恢复原来的值 colorDialog.Color Color.Black; if (colorDialog.ShowDialog() ! DialogResult.Cancel) { //将当前选定的文字改变颜色 rtMain.SelectionColor colorDialog.Color; } rtMain.Focus(); } //插入图片 private void 图像PToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog new OpenFileDialog(); //初始目录 // openFileDialog.InitialDirectory d:\\; //图片格式 openFileDialog.Filter 位图文件|*.bmp|gif文件|*.gif|TIFF文件|*.tif|jpg文件|*.jpg|所有文件|*.*; //还原当前目录 openFileDialog.RestoreDirectory true; //默认的文件格式 openFileDialog.FilterIndex 1; if (openFileDialog.ShowDialog() DialogResult.OK) { try { string fName openFileDialog.FileName; //加载图片 Bitmap img new Bitmap(fName); //添加到ZYBTextBox中 rtMain.InsertImage(img); } catch (System.IO.FileNotFoundException) { MessageBox.Show(没有找到文件, 错误, MessageBoxButtons.OK, MessageBoxIcon.Error); } } rtMain.Focus(); } //左对齐 public void 左对齐LToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.SelectionAlignment HorizontalAlignment.Left; } // 居中 public void 居中EToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.SelectionAlignment HorizontalAlignment.Center; } //右对齐 public void 右对齐RToolStripMenuItem_Click(object sender, EventArgs e) { rtMain.SelectionAlignment HorizontalAlignment.Right; } // 保存 public void 保存SToolStripMenuItem_Click(object sender, EventArgs e) { if (strFileName ! ) rtMain.SaveFile(strFileName); else 另存为AToolStripMenuItem_Click(sender, e); } //新建 public void 新建NToolStripMenuItem_Click(object sender, EventArgs e) { if (MessageBox.Show(要保存现有文件吗, 提示对话框, MessageBoxButtons.YesNo, MessageBoxIcon.Question) DialogResult.Yes) 保存SToolStripMenuItem_Click(sender, e); else { strFileName ; rtMain.Clear(); } this.Text 新建文档 --记事本; } //处理粗体显示 public void tsbBold_Click(object sender, EventArgs e) { //处理粗体显示 System.Drawing.Font oldFont rtMain.SelectionFont; System.Drawing.Font newFont; if (oldFont.Bold) newFont new Font(oldFont, oldFont.Style ~FontStyle.Bold); else newFont new Font(oldFont, oldFont.Style | FontStyle.Bold); rtMain.SelectionFont newFont; rtMain.Focus(); } //处理斜体显示 public void ttsbItalic_Click(object sender, EventArgs e) { //处理斜体显示 System.Drawing.Font oldFont rtMain.SelectionFont; System.Drawing.Font newFont; if (oldFont.Italic) newFont new Font(oldFont, oldFont.Style ~FontStyle.Italic); else newFont new Font(oldFont, oldFont.Style | FontStyle.Italic); rtMain.SelectionFont newFont; rtMain.Focus(); } //处理下划线显示 public void ttsbUnderLine_Click(object sender, EventArgs e) { //处理下划线显示 System.Drawing.Font oldFont rtMain.SelectionFont; ; System.Drawing.Font newFont; if(oldFont.Underline) newFont new Font(oldFont,oldFont.Style~FontStyle.Underline); else newFont new Font(oldFont,oldFont.Style|FontStyle.Underline); rtMain.SelectionFont newFont; rtMain.Focus(); } //初始化字体选择 private void MainForm_Load(object sender, EventArgs e) { MainForm parent (MainForm)this.MdiParent; //初始化字体选择 foreach (FontFamily oneFontFamily in FontFamily.Families) { parent.m_tscbFont.Items.Add(oneFontFamily.Name); } parent.m_tscbFont.SelectedItem 宋体; parent.m_tscbSize.SelectedIndex 2; } //字体选择 private void tscbFont_SelectedIndexChanged(object sender, EventArgs e) { MainForm parent (MainForm)this.MdiParent; if (parent.m_tscbSize.SelectedItem null) return; FontFamily family new FontFamily(parent.m_tscbFont.SelectedItem.ToString()); float emSize float.Parse(parent.m_tscbSize.SelectedItem.ToString()); System.Drawing.Font newFont new Font(family,emSize);; rtMain.SelectionFont newFont; rtMain.Focus(); } //关闭时保存文件 private void ChildForm_FormClosed(object sender, FormClosedEventArgs e) { if (MessageBox.Show(要保存现有文件吗, 提示对话框, MessageBoxButtons.YesNo, MessageBoxIcon.Question) DialogResult.Yes) 保存SToolStripMenuItem_Click(sender, e); } }}