ChatRichTextBox : RichTextBox
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using ImageOleLib;
using DynamicGifLib;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Diagnostics; namespace EmotionPanel
{ public class ChatRichTextBox : RichTextBox
{ RichEditOle ole;
private IRichEditOle _richEditOle;
private Dictionary<int, REOBJECT> _oleObjectList;
private int _index; #region Interop-Defines
[StructLayout(LayoutKind.Sequential)]
public struct CHARFORMAT2_STRUCT
{
public UInt32 cbSize;
public UInt32 dwMask;
public UInt32 dwEffects;
public Int32 yHeight;
public Int32 yOffset;
public Int32 crTextColor;
public byte bCharSet;
public byte bPitchAndFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public char[] szFaceName;
public UInt16 wWeight;
public UInt16 sSpacing;
public int crBackColor; // Color.ToArgb() -> int
public int lcid;
public int dwReserved;
public Int16 sStyle;
public Int16 wKerning;
public byte bUnderlineType;
public byte bAnimation;
public byte bRevAuthor;
public byte bReserved1;
} [DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); private const int WM_USER = 0x0400;
private const int EM_GETCHARFORMAT = WM_USER + ;
public const int EM_SETCHARFORMAT = WM_USER + ; public const int SCF_SELECTION = 0x0001;
private const int SCF_WORD = 0x0002;
private const int SCF_ALL = 0x0004; #region CHARFORMAT2 Flags
private const UInt32 CFE_BOLD = 0x0001;
private const UInt32 CFE_ITALIC = 0x0002;
private const UInt32 CFE_UNDERLINE = 0x0004;
private const UInt32 CFE_STRIKEOUT = 0x0008;
private const UInt32 CFE_PROTECTED = 0x0010;
public const UInt32 CFE_LINK = 0x0020;
private const UInt32 CFE_AUTOCOLOR = 0x40000000;
private const UInt32 CFE_SUBSCRIPT = 0x00010000; /* Superscript and subscript are */
private const UInt32 CFE_SUPERSCRIPT = 0x00020000; /* mutually exclusive */ private const int CFM_SMALLCAPS = 0x0040; /* (*) */
private const int CFM_ALLCAPS = 0x0080; /* Displayed by 3.0 */
private const int CFM_HIDDEN = 0x0100; /* Hidden by 3.0 */
private const int CFM_OUTLINE = 0x0200; /* (*) */
private const int CFM_SHADOW = 0x0400; /* (*) */
private const int CFM_EMBOSS = 0x0800; /* (*) */
private const int CFM_IMPRINT = 0x1000; /* (*) */
private const int CFM_DISABLED = 0x2000;
private const int CFM_REVISED = 0x4000; private const int CFM_BACKCOLOR = 0x04000000;
private const int CFM_LCID = 0x02000000;
private const int CFM_UNDERLINETYPE = 0x00800000; /* Many displayed by 3.0 */
private const int CFM_WEIGHT = 0x00400000;
private const int CFM_SPACING = 0x00200000; /* Displayed by 3.0 */
private const int CFM_KERNING = 0x00100000; /* (*) */
private const int CFM_STYLE = 0x00080000; /* (*) */
private const int CFM_ANIMATION = 0x00040000; /* (*) */
private const int CFM_REVAUTHOR = 0x00008000; private const UInt32 CFM_BOLD = 0x00000001;
private const UInt32 CFM_ITALIC = 0x00000002;
private const UInt32 CFM_UNDERLINE = 0x00000004;
private const UInt32 CFM_STRIKEOUT = 0x00000008;
private const UInt32 CFM_PROTECTED = 0x00000010;
public const UInt32 CFM_LINK = 0x00000020;
private const UInt32 CFM_SIZE = 0x80000000;
private const UInt32 CFM_COLOR = 0x40000000;
private const UInt32 CFM_FACE = 0x20000000;
private const UInt32 CFM_OFFSET = 0x10000000;
private const UInt32 CFM_CHARSET = 0x08000000;
private const UInt32 CFM_SUBSCRIPT = CFE_SUBSCRIPT | CFE_SUPERSCRIPT;
private const UInt32 CFM_SUPERSCRIPT = CFM_SUBSCRIPT; private const byte CFU_UNDERLINENONE = 0x00000000;
private const byte CFU_UNDERLINE = 0x00000001;
private const byte CFU_UNDERLINEWORD = 0x00000002; /* (*) displayed as ordinary underline */
private const byte CFU_UNDERLINEDOUBLE = 0x00000003; /* (*) displayed as ordinary underline */
private const byte CFU_UNDERLINEDOTTED = 0x00000004;
private const byte CFU_UNDERLINEDASH = 0x00000005;
private const byte CFU_UNDERLINEDASHDOT = 0x00000006;
private const byte CFU_UNDERLINEDASHDOTDOT = 0x00000007;
private const byte CFU_UNDERLINEWAVE = 0x00000008;
private const byte CFU_UNDERLINETHICK = 0x00000009;
private const byte CFU_UNDERLINEHAIRLINE = 0x0000000A; /* (*) displayed as ordinary underline */ #endregion #endregion public ChatRichTextBox()
: base()
{
base.BorderStyle = BorderStyle.FixedSingle;
this.DetectUrls = false;
} public Dictionary<int, REOBJECT> OleObjectList
{
get
{
if (_oleObjectList == null)
{
_oleObjectList = new Dictionary<int, REOBJECT>();
}
return _oleObjectList;
}
} internal RichEditOle RichEditOle
{
get
{
if (ole == null)
{
if (base.IsHandleCreated)
{
ole = new RichEditOle(this);
}
} return ole;
}
} public bool InsertImageUseImageOle(string path)
{
try
{
IGifAnimator gif = new GifAnimatorClass();
gif.LoadFromFile(path);
gif.TriggerFrameChange();
if (gif is IOleObject)
{
int index = _index ++;
REOBJECT reObj = RichEditOle.InsertOleObject(
(IOleObject)gif,
index);
RichEditOle.UpdateObjects(reObj.cp);
OleObjectList.Add(index, reObj);
return true;
}
return false;
}
catch (Exception)
{
return false;
}
} public bool InsertImageUseDynamic(string path)
{
try
{
IDynamicGif gif = new DynamicGifClass();
gif.LoadFromFile(path);
gif.Play();
if (gif is IOleObject)
{
int index = _index++;
REOBJECT reObj = RichEditOle.InsertOleObject(
(IOleObject)gif,
index);
RichEditOle.UpdateObjects(reObj.cp);
OleObjectList.Add(index, reObj);
return true;
}
return false;
}
catch (Exception)
{
return false;
}
} public bool InsertImageUseGifBox(Image path)
{
try
{
GifBox gif = new GifBox();
gif.BackColor = base.BackColor;
gif.Image = path;
RichEditOle.InsertControl(gif);
return true;
}
catch (Exception)
{
return false;
}
} public bool InsertImageUseGifBox(string path)
{
try
{
GifBox gif = new GifBox();
gif.BackColor = base.BackColor;
gif.Image = Image.FromFile(path);
RichEditOle.InsertControl(gif);
return true;
}
catch (Exception)
{
return false;
}
} [DefaultValue(false)]
public new bool DetectUrls
{
get { return base.DetectUrls; }
set { base.DetectUrls = value; }
} /// <summary>
/// Insert a given text as a link into the RichTextBox at the current insert position.
/// </summary>
/// <param name="text">Text to be inserted</param>
public void InsertLink(string text)
{
InsertLink(text, this.SelectionStart);
} /// <summary>
/// Insert a given text at a given position as a link.
/// </summary>
/// <param name="text">Text to be inserted</param>
/// <param name="position">Insert position</param>
public void InsertLink(string text, int position)
{
if (position < || position > this.Text.Length)
throw new ArgumentOutOfRangeException("position"); this.SelectionStart = position;
this.SelectedText = text;
this.Select(position, text.Length);
this.SetSelectionLink(true);
this.Select(position + text.Length, );
} /// <summary>
/// Insert a given text at at the current input position as a link.
/// The link text is followed by a hash (#) and the given hyperlink text, both of
/// them invisible.
/// When clicked on, the whole link text and hyperlink string are given in the
/// LinkClickedEventArgs.
/// </summary>
/// <param name="text">Text to be inserted</param>
/// <param name="hyperlink">Invisible hyperlink string to be inserted</param>
public void InsertLink(string text, string hyperlink)
{
InsertLink(text, hyperlink, this.SelectionStart);
} /// <summary>
/// Insert a given text at a given position as a link. The link text is followed by
/// a hash (#) and the given hyperlink text, both of them invisible.
/// When clicked on, the whole link text and hyperlink string are given in the
/// LinkClickedEventArgs.
/// </summary>
/// <param name="text">Text to be inserted</param>
/// <param name="hyperlink">Invisible hyperlink string to be inserted</param>
/// <param name="position">Insert position</param>
public void InsertLink(string text, string hyperlink, int position)
{
if (position < || position > this.Text.Length)
throw new ArgumentOutOfRangeException("position"); this.SelectionStart = position;
//this.SelectedRtf = @"{\rtf1\ansi "+text+@"\v #"+hyperlink+@"\v0}";// 只能显示英文
this.SelectedRtf = @"{\rtf1\ansi\cpg936 " + text + @"\v #" + hyperlink + @"\v0}"; // 可以显示中文
this.Select(position, text.Length + hyperlink.Length + );
this.SetSelectionLink(true);
this.Select(position + text.Length + hyperlink.Length + , );
} /// <summary>
/// Set the current selection's link style
/// </summary>
/// <param name="link">true: set link style, false: clear link style</param>
public void SetSelectionLink(bool link)
{
SetSelectionStyle(CFM_LINK, link ? CFE_LINK : );
}
/// <summary>
/// Get the link style for the current selection
/// </summary>
/// <returns>0: link style not set, 1: link style set, -1: mixed</returns>
public int GetSelectionLink()
{
return GetSelectionStyle(CFM_LINK, CFE_LINK);
} private void SetSelectionStyle(UInt32 mask, UInt32 effect)
{
CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
cf.cbSize = (UInt32)Marshal.SizeOf(cf);
cf.dwMask = mask;
cf.dwEffects = effect; IntPtr wpar = new IntPtr(SCF_SELECTION);
IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lpar, false); IntPtr res = SendMessage(Handle, EM_SETCHARFORMAT, wpar, lpar); Marshal.FreeCoTaskMem(lpar);
} private int GetSelectionStyle(UInt32 mask, UInt32 effect)
{
CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
cf.cbSize = (UInt32)Marshal.SizeOf(cf);
cf.szFaceName = new char[]; IntPtr wpar = new IntPtr(SCF_SELECTION);
IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lpar, false); IntPtr res = SendMessage(Handle, EM_GETCHARFORMAT, wpar, lpar); cf = (CHARFORMAT2_STRUCT)Marshal.PtrToStructure(lpar, typeof(CHARFORMAT2_STRUCT)); int state;
// dwMask holds the information which properties are consistent throughout the selection:
if ((cf.dwMask & mask) == mask)
{
if ((cf.dwEffects & effect) == effect)
state = ;
else
state = ;
}
else
{
state = -;
} Marshal.FreeCoTaskMem(lpar);
return state;
}
///////////////////////////////////////////
///////////////////////////////////////////// IRichEditOle richEditOle
{
get
{
if (this._richEditOle == null)
{
IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
IntPtr richEditOleIntPtr = IntPtr.Zero;
Marshal.WriteIntPtr(ptr, IntPtr.Zero);
try
{
int msgResult = (int)SendMessage(this.Handle, EmotionPanel.NativeMethods.EM_GETOLEINTERFACE, IntPtr.Zero, ptr);
if (msgResult != )
{
IntPtr intPtr = Marshal.ReadIntPtr(ptr);
try
{
if (intPtr != IntPtr.Zero)
{
Guid guid = new Guid("00020D00-0000-0000-c000-000000000046");
Marshal.QueryInterface(intPtr, ref guid, out richEditOleIntPtr); this._richEditOle = (IRichEditOle)Marshal.GetTypedObjectForIUnknown(richEditOleIntPtr, typeof(IRichEditOle));
}
}
finally
{
Marshal.Release(intPtr);
}
}
}
catch (Exception err)
{
Trace.WriteLine(err.ToString());
}
finally
{
Marshal.FreeCoTaskMem(ptr);
}
}
return this._richEditOle;
}
} public new bool ReadOnly { get; set; } protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x0100:
if (this.ReadOnly)
return;
break;
case 0X0102:
if (this.ReadOnly)
return;
break;
default:
break;
}
base.WndProc(ref m);
} List<MyGIF> gifList = new List<MyGIF>();
Panel gifPanel = new Panel();
public void ClearGif()
{
this.gifPanel.Controls.Clear();
this.gifList.Clear();
} public void InsertGIF(string Name, Image Data)
{ MyGIF gif = new MyGIF(Name, Data);
gif.Box.Invalidate();
this.gifPanel.Controls.Add(gif.Box);
this.gifList.Add(gif); //RichEditOle ole = new RichEditOle(this);
ole.InsertControl(gif); this.Invalidate(); } public string GetGIFInfo()
{
string imageInfo = "";
REOBJECT reObject = new REOBJECT();
for (int i = ; i < this.richEditOle.GetObjectCount(); i++)
{
this.richEditOle.GetObject(i, reObject, GETOBJECTOPTIONS.REO_GETOBJ_ALL_INTERFACES);
MyGIF gif = this.gifList.Find(p => p != null && p.Index == reObject.dwUser);
if (gif != null)
{
imageInfo += reObject.cp.ToString() + ":" + gif.Name + "|";
}
}
return imageInfo;
} private void SetSelectionStyle()
{
CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
cf.cbSize = (UInt32)Marshal.SizeOf(cf);
cf.dwMask = CFM_LINK;
cf.dwEffects = CFE_LINK; IntPtr wpar = new IntPtr(SCF_SELECTION);
IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lpar, false); IntPtr res = (IntPtr)SendMessage(Handle, EM_SETCHARFORMAT, wpar, lpar); Marshal.FreeCoTaskMem(lpar);
} public void SetFont(string Name, bool Bold, bool Italic, bool Underline, Color Color, float Size)
{
FontStyle style = FontStyle.Regular;
if (Bold) style |= FontStyle.Bold;
if (Italic) style |= FontStyle.Italic;
if (Underline) style |= FontStyle.Underline; this.Font = new Font(Name, Size, style);
this.ForeColor = Color;
} public string GetTextToSend()
{
string value = string.Empty;
value += "\\n" + this.Font.Name;
value += "\\b" + (this.Font.Bold ? "" : "");
value += "\\i" + (this.Font.Italic ? "" : "");
value += "\\u" + (this.Font.Underline ? "" : "");
value += "\\s" + this.Font.Size.ToString();
value += "\\c" + ColorTranslator.ToHtml(this.ForeColor);
value += "\\t" + this.Text;
value += "\\p" + this.GetGIFInfo(); return value;
}
}
}
ChatRichTextBox : RichTextBox的更多相关文章
- WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...
- 支持同步滚动的RichTextbox控件
using System.Windows.Forms; public class SynchronizedScrollRichTextBox : System.Windows.Forms.RichTe ...
- WPF下的Richtextbox中实现表格合并,添加删除行列等功能
.Net中已有现在的方法实现这些功能,不过可能是由于未完善,未把方法公开出来.只能用反射的方法去调用它. 详细信息可以查看.Net Framework 的源代码 http://referencesou ...
- WPF RichTextBox 做内容展示框 滚动条控制判定是否阅读完成
一.项目背景: 最近,做项目,因为是金融项目,客户登录交易的时候,有一个提示框,就是告知客户要“入市需谨慎”等等,想必大家都遇到这样的场景,当然,这种提示是没人会看的,不过作为交易所,这样的提示又必不 ...
- 将richTextBox中的内容写入txt文件发现不换行(解决方法),在richTextBox指定位置插入文字
string pathname = dt.ToString().Replace(":", ""); string str = richTextBoxResult ...
- RichTextBox实现鼠标右键(剪切,复制,粘贴)功能
private static void InitRichTextBoxContextMenu(RichTextBox textBox) { //创建剪切子菜单 var cutMenuItem = ne ...
- 如何在RichTextBox中改变多个字符串的颜色以及字体
目标:传入目标富文本框以及需要查找的字符串,如果文本框中存在字符串,则改变其颜色和字体 可能因为这个问题比较简单,在网上找了很久,也没有一个好的方法.少有的一些方法,也只是改变第一个找到的字符串的颜色 ...
- 初学c# -- 学习笔记(七) RichTextBox支持GIF
园子里许明吉博客写的一篇,刚好用到这个,写的非常好.转过来了 不过在应用中也有一些问题,win10下不能中文输入,凑合着进行了修改, 下面是原来的代码: private void button2_Cl ...
- WinForm richtextbox 关键字变红色
private void HilightRichText(RichTextBox control, string hilightString) { int nSel ...
随机推荐
- Hdoop日记Day10---RPC机制
一.RPC(Remote Procedure Call)简介 RPC 是远程过程调用(Remote Procedure Call),即远程调用其他虚拟机中运行的javaobject.RPC 是一种客户 ...
- SQLServer性能优化之 nolock,大幅提升数据库查询性能
公司数据库随着时间的增长,数据越来越多,查询速度也越来越慢.进数据库看了一下,几十万调的数据,查询起来确实很费时间. 要提升SQL的查询效能,一般来说大家会以建立索引(index)为第一考虑.其实除了 ...
- SQL Server 性能优化之——T-SQL TVF和标量函数
阅读导航 1. TVF(表-值行数Table-Valued Functions) a. 创建TVF b. 使用TVF的低性能T-SQL c. 使用临时表 ...
- Java mac 上编写Java代码
看视频学JAVA,不想下载 notepad++之类的,虽然知道mac有内嵌的JAVA sdk ,但是还是不知道怎么编写,今天终于编写了我的第一个JAVA程序,还是以 Hello World 开始吧 1 ...
- 去除NSString里面的空格
NSString *password = @"12 34"; [password stringByTrimmingCharactersInSet:[NSCharacterSet ...
- 每天一个linux命令(53):route命令
Linux系统的route命令用于显示和操作IP路由表(show / manipulate the IP routing table).要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或 ...
- atitit.TokenService v3 qb1 token服务模块的设计 新特性.docx
atitit.TokenService v3 qb1 token服务模块的设计 新特性.docx 1.1. V3 新特性1 1.2. V2 新特性1 2. Token的归类1 3. Token的用途 ...
- Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途
Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途 1.1. 高斯模糊 的原理(周边像素的平均值+正态分布的权重1 1.2. 高斯模糊 的用途(磨皮,毛玻璃效果,背景虚化 ...
- Android应用中使用AsyncHttpClient来异步网络数据(转载)
摘要: 首先下载AsyncHttpClient的库文件,可以自行搜索,可以到下面地址下载 http://download.csdn.net/detail/xujinyang1234/5767419 测 ...
- 通过shape-outside来设置文字环绕时的形状
现在真是越来越注重用户体验了,而"shape-outside"就是其中一个能让网页排版更友好的一个属性. 默认文字是根据图片的边进行的. 但现在我们完全有能力去改变这一行为,下面是 ...