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的更多相关文章

  1. WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...

  2. 支持同步滚动的RichTextbox控件

    using System.Windows.Forms; public class SynchronizedScrollRichTextBox : System.Windows.Forms.RichTe ...

  3. WPF下的Richtextbox中实现表格合并,添加删除行列等功能

    .Net中已有现在的方法实现这些功能,不过可能是由于未完善,未把方法公开出来.只能用反射的方法去调用它. 详细信息可以查看.Net Framework 的源代码 http://referencesou ...

  4. WPF RichTextBox 做内容展示框 滚动条控制判定是否阅读完成

    一.项目背景: 最近,做项目,因为是金融项目,客户登录交易的时候,有一个提示框,就是告知客户要“入市需谨慎”等等,想必大家都遇到这样的场景,当然,这种提示是没人会看的,不过作为交易所,这样的提示又必不 ...

  5. 将richTextBox中的内容写入txt文件发现不换行(解决方法),在richTextBox指定位置插入文字

    string pathname = dt.ToString().Replace(":", ""); string str = richTextBoxResult ...

  6. RichTextBox实现鼠标右键(剪切,复制,粘贴)功能

    private static void InitRichTextBoxContextMenu(RichTextBox textBox) { //创建剪切子菜单 var cutMenuItem = ne ...

  7. 如何在RichTextBox中改变多个字符串的颜色以及字体

    目标:传入目标富文本框以及需要查找的字符串,如果文本框中存在字符串,则改变其颜色和字体 可能因为这个问题比较简单,在网上找了很久,也没有一个好的方法.少有的一些方法,也只是改变第一个找到的字符串的颜色 ...

  8. 初学c# -- 学习笔记(七) RichTextBox支持GIF

    园子里许明吉博客写的一篇,刚好用到这个,写的非常好.转过来了 不过在应用中也有一些问题,win10下不能中文输入,凑合着进行了修改, 下面是原来的代码: private void button2_Cl ...

  9. WinForm richtextbox 关键字变红色

    private void HilightRichText(RichTextBox control, string hilightString)        {            int nSel ...

随机推荐

  1. Hdoop日记Day10---RPC机制

    一.RPC(Remote Procedure Call)简介 RPC 是远程过程调用(Remote Procedure Call),即远程调用其他虚拟机中运行的javaobject.RPC 是一种客户 ...

  2. SQLServer性能优化之 nolock,大幅提升数据库查询性能

    公司数据库随着时间的增长,数据越来越多,查询速度也越来越慢.进数据库看了一下,几十万调的数据,查询起来确实很费时间. 要提升SQL的查询效能,一般来说大家会以建立索引(index)为第一考虑.其实除了 ...

  3. SQL Server 性能优化之——T-SQL TVF和标量函数

    阅读导航 1. TVF(表-值行数Table-Valued Functions)         a. 创建TVF         b. 使用TVF的低性能T-SQL         c. 使用临时表 ...

  4. Java mac 上编写Java代码

    看视频学JAVA,不想下载 notepad++之类的,虽然知道mac有内嵌的JAVA sdk ,但是还是不知道怎么编写,今天终于编写了我的第一个JAVA程序,还是以 Hello World 开始吧 1 ...

  5. 去除NSString里面的空格

    NSString *password = @"12  34"; [password stringByTrimmingCharactersInSet:[NSCharacterSet ...

  6. 每天一个linux命令(53):route命令

    Linux系统的route命令用于显示和操作IP路由表(show / manipulate the IP routing table).要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或 ...

  7. 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的用途 ...

  8. Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途

    Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途 1.1. 高斯模糊 的原理(周边像素的平均值+正态分布的权重1 1.2. 高斯模糊 的用途(磨皮,毛玻璃效果,背景虚化 ...

  9. Android应用中使用AsyncHttpClient来异步网络数据(转载)

    摘要: 首先下载AsyncHttpClient的库文件,可以自行搜索,可以到下面地址下载 http://download.csdn.net/detail/xujinyang1234/5767419 测 ...

  10. 通过shape-outside来设置文字环绕时的形状

    现在真是越来越注重用户体验了,而"shape-outside"就是其中一个能让网页排版更友好的一个属性. 默认文字是根据图片的边进行的. 但现在我们完全有能力去改变这一行为,下面是 ...