ChatRichTextBox : RichTextBox
2016-12-10 20:24
411 查看
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 = 32)] 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 + 58; public const int EM_SETCHARFORMAT = WM_USER + 68; 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>(10); } 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 < 0 || 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, 0); } /// <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 < 0 || 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 + 1); this.SetSelectionLink(true); this.Select(position + text.Length + hyperlink.Length + 1, 0); } /// <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 : 0); } /// <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[32]; 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 = 1; else state = 0; } else { state = -1; } 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 != 0) { 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 = 0; 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 ? "1" : "0"); value += "\\i" + (this.Font.Italic ? "1" : "0"); value += "\\u" + (this.Font.Underline ? "1" : "0"); value += "\\s" + this.Font.Size.ToString(); value += "\\c" + ColorTranslator.ToHtml(this.ForeColor); value += "\\t" + this.Text; value += "\\p" + this.GetGIFInfo(); return value; } } }
相关文章推荐
- GB2312 编码(转)
- 力学现象动画演示——真空状态下的自由落体运动
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- nyoj Thepartialsumproblem(DFS)
- Android自定义View之Activity页面的组成
- sdut oj面向对象程序设计上机练习十二(运算符重载)
- 环境搭建之rabbitmq安装步骤(win64)
- 使用ycsb测试cassandra