学习笔记(七) RichTextBox支持GIF

时间:2021-07-06 04:39:23

园子里许明吉博客写的一篇,刚好用到这个,写的非常好。转过来了

不过在应用中也有一些问题,win10下不能中文输入,凑合着进行了修改,

下面是原来的代码:

private void button2_Click(object sender, EventArgs e) { IList<MemoryStream> _List = gifRichTextBox1.LoadSelectFile(); for (int i = 0; i != _List.Count; i++) { File.WriteAllBytes(@"C:\Temp\A" + i.ToString() + ".gif", _List[0].ToArray()); } } //添加一个GIF图形 private void button3_Click(object sender, EventArgs e) { gifRichTextBox1.AddFile(@"C:\Temp\0.gif"); } //获取当前的RTF文字 你可以直接保存这个到数据库 或则通过SOCKET发送出去. string _Text = ""; private void button1_Click(object sender, EventArgs e) { _Text = gifRichTextBox1.Rtf; } //重新显示RTF内容 private void button4_Click(object sender, EventArgs e) { gifRichTextBox1.Rtf = _Text; } 如果没有这个类..保存出的RTF数据..在其他RTF浏览的时候可能是个白色的矩形.. 下面是全部的类 using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Windows.Forms; using System.Drawing; namespace Zgke.WindowFrom.Window.Controls.UserControls { /// <summary> /// RichTextBox支持 GIF图形 /// zgke@sina.com /// qq:116149 /// </summary> public class GifRichTextBox : RichTextBox { public GifRichTextBox() { } /// <summary> /// 重绘 /// </summary> /// <param></param> protected override void WndProc(ref Message m) { if (m.Msg == 0xF) { foreach (Control _SubControl in base.Controls) { _SubControl.Tag = "1"; } GetRichTextObjRectangle(); for (int i = 0; i != base.Controls.Count; i++) { if (base.Controls[i].Tag.ToString() == "1") { base.Controls.RemoveAt(i); i--; } } } base.WndProc(ref m); } /// <summary> /// 添加一个文件资源到RTF数据 /// </summary> /// <param>文件路径</param> public void AddFile(string p_FileFullPath) { byte[] _FileBytes = File.ReadAllBytes(p_FileFullPath); Image _Image = Image.FromStream(new MemoryStream(_FileBytes)); string _Guid = BitConverter.ToString(Guid.NewGuid().ToByteArray()).Replace("-", ""); StringBuilder _RtfText = new StringBuilder(@"{\rtf1\ansi\ansicpg936\deff0\deflang1033\deflangfe2052{\fonttbl{\f0\fnil\fcharset134 \‘cb\‘ce\‘cc\‘e5;}}\uc1\pard\lang2052\f0\fs18{\object\objemb{\*\objclass Paint.Picture}"); int _Width = _Image.Width * 15; int _Height = _Image.Height * 15; _RtfText.Append(@"\objw" + _Width.ToString() + @"\objh" + _Height.ToString()); _RtfText.AppendLine(@"{\*\objdata"); _RtfText.AppendLine(@"010500000200000007000000504272757368000000000000000000" + BitConverter.ToString(BitConverter.GetBytes(_FileBytes.Length + 20)).Replace("-", "")); _RtfText.Append("7A676B65" + _Guid); //标记 _RtfText.AppendLine(BitConverter.ToString(_FileBytes).Replace("-", "")); _RtfText.AppendLine(@"0105000000000000}{\result{\pict\wmetafile0}}}}"); base.SelectedRtf = _RtfText.ToString(); } /// <summary> /// 获取选择的文件 /// </summary> /// <returns>文件列表</returns> public IList<MemoryStream> LoadSelectFile() { IList<MemoryStream> _FileList = new List<MemoryStream>(); int _Index = base.SelectedRtf.IndexOf(@"{\*\objdata"); if (_Index == -1) return _FileList; while (_Index != -1) { MemoryStream _File = new MemoryStream(); _Index += 80; string _LengthText = base.SelectedRtf.Substring(_Index, 8); int _Length = BitConverter.ToInt32(new byte[] { Convert.ToByte(_LengthText.Substring(0, 2), 16), Convert.ToByte(_LengthText.Substring(2, 2), 16), Convert.ToByte(_LengthText.Substring(4, 2), 16), Convert.ToByte(_LengthText.Substring(6, 2), 16) }, 0); _Index += 10; string _Head = base.SelectedRtf.Substring(_Index, 8); if (_Head.ToUpper() == "7A676B65") { _Index += 40; _Length -= 20; int _EndIndex = base.SelectedRtf.IndexOf("01050000", _Index); int _ReadIndex = 0; _FileList.Add(LoadMemoryStream(base.SelectedRtf.Substring(_Index, _EndIndex - _Index), ref _ReadIndex, _Length)); _Index = _EndIndex; } _Index = base.SelectedRtf.IndexOf(@"{\*\objdata", _Index); } return _FileList; } /// <summary> /// 获取图形或则改动PictureBox的位置 /// </summary> /// <param></param> private void PointFile(string p_Rtf, Point p_StarPoint, int p_Width, int p_Height) { int _Index = p_Rtf.IndexOf(@"{\*\objdata"); if (_Index == -1) return; _Index += 80; string _LengthText = p_Rtf.Substring(_Index, 8); int _Length = BitConverter.ToInt32(new byte[] { Convert.ToByte(_LengthText.Substring(0, 2), 16), Convert.ToByte(_LengthText.Substring(2, 2), 16), Convert.ToByte(_LengthText.Substring(4, 2), 16), Convert.ToByte(_LengthText.Substring(6, 2), 16) }, 0); _Index += 10; string _Head = p_Rtf.Substring(_Index, 8); if (_Head.ToUpper() != "7A676B65") return; //如果不是标记出来的 就不生成PictureBox _Index += 8; string _Guid = p_Rtf.Substring(_Index, 32); Control _Controls = base.Controls[_Guid]; if (_Controls == null) { PictureBox _PictureBox = new PictureBox(); _PictureBox.Name = _Guid; _PictureBox.Tag = "0"; _PictureBox.Location = p_StarPoint; _PictureBox.Size = new Size(p_Width, p_Height); _Index += 32; _Length -= 20; _PictureBox.Image = Image.FromStream(LoadMemoryStream(p_Rtf, ref _Index,_Length)); base.Controls.Add(_PictureBox); } else { _Controls.Location = p_StarPoint; _Controls.Size = new Size(p_Width, p_Height); _Controls.Tag = "0"; } } /// <summary> /// 根据RTF保存的内容获取内存流 /// </summary> /// <param>RTF</param> /// <param>开始位置</param> /// <param>读取数量</param> /// <returns>内存流</returns> private MemoryStream LoadMemoryStream(string p_Text,ref int p_Index,int p_Count) { MemoryStream _File =new MemoryStream(); char[] _Text = p_Text.ToCharArray(); for (int i = 0; i != p_Count; i++) { if (_Text[p_Index] == ‘\r‘ && _Text[p_Index + 1] == ‘\n‘) { i--; } else { _File.WriteByte(Convert.ToByte(_Text[p_Index].ToString() + _Text[p_Index + 1].ToString(), 16)); } p_Index += 2; } return _File; } /// <summary> /// 获取RICHTEXTBOX所有图形的位置 /// </summary> /// <param>RICHTEXTBOX</param> /// <returns>位置信息</returns> private void GetRichTextObjRectangle() { RichTextBox _RichText = new RichTextBox(); _RichText.Rtf = base.Rtf; int _Count = base.Text.Length; for (int i = 0; i != _Count; i++) { if (base.Text[i] == ‘ ‘) { _RichText.Select(i, 1); if (_RichText.SelectionType.ToString() == "Object") { Point _StarPoint = base.GetPositionFromCharIndex(i); System.Text.RegularExpressions.Regex _RegexWidth = new System.Text.RegularExpressions.Regex(@"(?<=\\objw)[^\\]+"); System.Text.RegularExpressions.Regex _RegexHeight = new System.Text.RegularExpressions.Regex(@"(?<=\\objh)[^{]+"); int _Width = 0; int _Height = 0; if (int.TryParse(_RegexWidth.Match(_RichText.SelectedRtf).Value, out _Width) && int.TryParse(_RegexHeight.Match(_RichText.SelectedRtf).Value, out _Height)) { _Width = _Width / 15; _Height = _Height / 15; PointFile(_RichText.SelectedRtf, _StarPoint, _Width, _Height); } } } } _RichText.Dispose(); } } }

修改:

if (m.Msg == 0xF)这句是重绘,改为

if (m.Msg == 0x0007)

改完后问题又来了,不切换焦点图片不能删掉,又在程序里写按键事件:

先建立组件

gr = new GifRichTextBox();//建立

gr.Height = 200;            

gr.Width = 200;

gr.BackColor = Color.White;gr.KeyUp += new KeyEventHandler(rich_KeyUp);//加按键事件

.......

.......

//判断是否delete键或backspace,失去焦点再获得