RichTextBox的非常好的实践
插入文本
在插入文本到RichTextBox时,文本必须是RTF格式。根据RTF指南说明RTF文档必须包含一个文档头和文档区域用于验证。文档头包含了文档中用到的语言和字体颜色列表。文档区域则是存储被格式的内容的地方。通过调用InsertTextAsRtf函数,RTF文档头被构建同时纯文本被格式化并加入到文档区域中。
public void InsertTextAsRtf(string _text, Font _font,
RtfColor _textColor, RtfColor _backColor)
{
StringBuilder _rtf = new StringBuilder();
// 追加文档头
_rtf.Append(RTF_HEADER);
// 创建字体表
_rtf.Append(GetFontTable(_font));
// 创建颜色表
_rtf.Append(GetColorTable(_textColor, _backColor));
// 创建文档区域
_rtf.Append(GetDocumentArea(_text, _font));
this.SelectedRtf = _rtf.ToString();
}
这里也有三个重载版本的InsertTextAsRtf函数:
public void InsertTextAsRtf(string _text)
{
InsertTextAsRtf(_text, this.Font);
}
public void InsertTextAsRtf(string _text, Font _font)
{
InsertTextAsRtf(_text, _font, textColor);
}
public void InsertTextAsRtf(string _text, Font _font, RtfColor _textColor)
{
InsertTextAsRtf(_text, _font, _textColor, highlightColor);
}
插入图片
当一个图片被粘贴到RichTextBox(或记事本,或word软件),图片先被嵌入到WMF然后被贴入文档中。InsertImage方法完成同样的工作,但是不通过剪贴板。根据RTF指南1.6版说明,插入的图片如果是bitmap,JPEG,GIF,PNG和增强 图元文件格式的可以直接插入而不用先嵌入到windows图元文件。但是,当那只是对于微软的word软件来说,对于写字板和RichTextBox,如果图片没有先嵌入到Windows图元文件中将被忽略。
图元文件
Windows图元文件在windows1.0的时候就被支持。它们在功能上受到限制并且也是为了向后兼容的目的才被windows窗体支持。.Net框架不支持直接创建windows图元文件,但是能够读取它们。.Net支持创建增强图元文件,因此增强 图元文件能通过非托管代码转换到Windows图元文件。GDI+包含了这个转换功能函数叫做EmfToWmfBits()。函数的形式如下:
[DllImportAttribute("gdiplus.dll")]
private static extern uint GdipEmfToWmfBits (IntPtr _hEmf, uint _bufferSize,
byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags);
_hEmf:要被转换的增强图元文件句柄。
_bufferSize:用于存储Windows图元文件的缓存大小。
_buffer:用于存储Windows图元文件的数组。
_mappingMode:图形的映射模式,该模式定义了要转换图像的方向和单位,还有需要的Windows API。在这个方案中我们使用MM_ANISOTROPIC。这个允许对图像在两个坐标轴 进行独立修改。
_flags:指示转换图元文件的设置
要嵌入到增强图元文件中的图像会被绘制到目标图元文件的图形环境中。然后再将增强图元文件转换到Windows图元文件。增强图元文件使用下面的构造函数来创建:
Metafile(Stream stream, IntPtr referencedHdc);
这个函数将创建一个新的增强图元文件用于设备环境referencedHdc中并存储这个图元文件到stream中。设备环境是一个结构,它包含了控件要显示文本和图形到具体的设备上的信息。图元文件必须被关联到设备环境中才能获取分辨率信息。每个图形对象都能提供一个句柄指向本身的设备环境。RichTextBox的设备环境通过GetGraphics方法来获取,然后调用GetHdc方法来获取最终的图形对象。
...
// 存储图元文件的内存流
_stream = new MemoryStream();
// 从RichTextBox的图形对象
using(_graphics = this.CreateGraphics())
{
// 从图形对象来获取设备环境
_hdc = _graphics.GetHdc();
// 从设备环境中创建一个增强 图元文件
_图元文件 = new 图元文件(_stream, _hdc);
// 释放设备环境
_graphics.ReleaseHdc(_hdc);
}
...
public void InsertTextAsRtf(string _text, Font _font,