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 ...
随机推荐
- java 多线程(ThreadPoolExecutor (补充))
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; impo ...
- Stealth视频教程学习笔记(第一章)
Stealth视频教程学习笔记(第一章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...
- Windows Live Writer 初次使用
Windows Live Writer 博客园文章的一款发布器,这篇文章就是通过其发布的,可以先在word中写好博客内容,直接粘贴到这里发布就OK,之前我都是先在Word中写好一份,然后在blogs ...
- 杂谈X509证书, Java Keystore与Jetty
很多人对JSSE组成部分的Key Tool 工具不太明白,希望本文能有帮助 科班出身的同学应该学过课程“密码学”, 这门课详细解释了现代对称加密的算法原理, 当时学的我云里雾里. 直到现在使用过SSL ...
- jQuery的选择器中的通配符[id^='code']
1.选择器 (1)通配符: $("input[id^='code']");//id属性以code开始的所有input标签 $("input[id$='code']&quo ...
- Vue的一个陷阱
最近做项目,上线前一直有个bug,不知道是什么原因引起的, vm.$set('needVerification', true); $('.verification-button').prop('dis ...
- xamarin误删vEthernet(internal Ethernet Port Windows Phone Emulator) 网络设备的处理。
昨天一不小心误删了xamarin 开发环境下的虚拟设备网络设备.名称为:vEthernet(internal Ethernet Port Windows Phone Emulator).导致原来能正确 ...
- 20_学生选课数据库SQL语句练习题1
25.查询95033班和95031班全体学生的记录. select * from STUDENT t,SCORE s where t.sclass=95033 or t.sclass=95031 26 ...
- ajax图片上传及FastDFS入门案例.
今天来开始写图片上传的功能, 现在的图片上传都讲求 上传完成后立刻回显且页面不刷新, 这里到底是怎么做的呢? 当然是借助于ajax了, 但是ajax又不能提交表单, 这里我们还要借助一个插件: jqu ...
- C#并行编程-相关概念
菜鸟初步学习,不对的地方请大神指教,参考<C#并行编程高级教程.pdf> 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C# ...