• ChatRichTextBox : RichTextBox


      1 using System;
      2 using System.Collections.Generic;
      3 using System.Text;
      4 using System.Windows.Forms;
      5 using System.Drawing;
      6 using ImageOleLib;
      7 using DynamicGifLib;
      8 using System.ComponentModel;
      9 using System.Runtime.InteropServices;
     10 using System.Diagnostics;
     11 
     12 namespace EmotionPanel
     13 { 
     14 
     15     public class ChatRichTextBox : RichTextBox
     16     {
     17 
     18         RichEditOle ole;
     19         private IRichEditOle _richEditOle;
     20         private Dictionary<int, REOBJECT> _oleObjectList;
     21         private int _index;
     22 
     23         #region Interop-Defines
     24         [StructLayout(LayoutKind.Sequential)]
     25         public struct CHARFORMAT2_STRUCT
     26         {
     27             public UInt32 cbSize;
     28             public UInt32 dwMask;
     29             public UInt32 dwEffects;
     30             public Int32 yHeight;
     31             public Int32 yOffset;
     32             public Int32 crTextColor;
     33             public byte bCharSet;
     34             public byte bPitchAndFamily;
     35             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
     36             public char[] szFaceName;
     37             public UInt16 wWeight;
     38             public UInt16 sSpacing;
     39             public int crBackColor; // Color.ToArgb() -> int
     40             public int lcid;
     41             public int dwReserved;
     42             public Int16 sStyle;
     43             public Int16 wKerning;
     44             public byte bUnderlineType;
     45             public byte bAnimation;
     46             public byte bRevAuthor;
     47             public byte bReserved1;
     48         }
     49 
     50         [DllImport("user32.dll", CharSet = CharSet.Auto)]
     51         public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
     52 
     53         private const int WM_USER = 0x0400;
     54         private const int EM_GETCHARFORMAT = WM_USER + 58;
     55         public const int EM_SETCHARFORMAT = WM_USER + 68;
     56 
     57         public const int SCF_SELECTION = 0x0001;
     58         private const int SCF_WORD = 0x0002;
     59         private const int SCF_ALL = 0x0004;
     60 
     61         #region CHARFORMAT2 Flags
     62         private const UInt32 CFE_BOLD = 0x0001;
     63         private const UInt32 CFE_ITALIC = 0x0002;
     64         private const UInt32 CFE_UNDERLINE = 0x0004;
     65         private const UInt32 CFE_STRIKEOUT = 0x0008;
     66         private const UInt32 CFE_PROTECTED = 0x0010;
     67         public const UInt32 CFE_LINK = 0x0020;
     68         private const UInt32 CFE_AUTOCOLOR = 0x40000000;
     69         private const UInt32 CFE_SUBSCRIPT = 0x00010000;        /* Superscript and subscript are */
     70         private const UInt32 CFE_SUPERSCRIPT = 0x00020000;        /*  mutually exclusive             */
     71 
     72         private const int CFM_SMALLCAPS = 0x0040;            /* (*)    */
     73         private const int CFM_ALLCAPS = 0x0080;            /* Displayed by 3.0    */
     74         private const int CFM_HIDDEN = 0x0100;            /* Hidden by 3.0 */
     75         private const int CFM_OUTLINE = 0x0200;            /* (*)    */
     76         private const int CFM_SHADOW = 0x0400;            /* (*)    */
     77         private const int CFM_EMBOSS = 0x0800;            /* (*)    */
     78         private const int CFM_IMPRINT = 0x1000;            /* (*)    */
     79         private const int CFM_DISABLED = 0x2000;
     80         private const int CFM_REVISED = 0x4000;
     81 
     82         private const int CFM_BACKCOLOR = 0x04000000;
     83         private const int CFM_LCID = 0x02000000;
     84         private const int CFM_UNDERLINETYPE = 0x00800000;        /* Many displayed by 3.0 */
     85         private const int CFM_WEIGHT = 0x00400000;
     86         private const int CFM_SPACING = 0x00200000;        /* Displayed by 3.0    */
     87         private const int CFM_KERNING = 0x00100000;        /* (*)    */
     88         private const int CFM_STYLE = 0x00080000;        /* (*)    */
     89         private const int CFM_ANIMATION = 0x00040000;        /* (*)    */
     90         private const int CFM_REVAUTHOR = 0x00008000;
     91 
     92 
     93         private const UInt32 CFM_BOLD = 0x00000001;
     94         private const UInt32 CFM_ITALIC = 0x00000002;
     95         private const UInt32 CFM_UNDERLINE = 0x00000004;
     96         private const UInt32 CFM_STRIKEOUT = 0x00000008;
     97         private const UInt32 CFM_PROTECTED = 0x00000010;
     98         public const UInt32 CFM_LINK = 0x00000020;
     99         private const UInt32 CFM_SIZE = 0x80000000;
    100         private const UInt32 CFM_COLOR = 0x40000000;
    101         private const UInt32 CFM_FACE = 0x20000000;
    102         private const UInt32 CFM_OFFSET = 0x10000000;
    103         private const UInt32 CFM_CHARSET = 0x08000000;
    104         private const UInt32 CFM_SUBSCRIPT = CFE_SUBSCRIPT | CFE_SUPERSCRIPT;
    105         private const UInt32 CFM_SUPERSCRIPT = CFM_SUBSCRIPT;
    106 
    107         private const byte CFU_UNDERLINENONE = 0x00000000;
    108         private const byte CFU_UNDERLINE = 0x00000001;
    109         private const byte CFU_UNDERLINEWORD = 0x00000002; /* (*) displayed as ordinary underline    */
    110         private const byte CFU_UNDERLINEDOUBLE = 0x00000003; /* (*) displayed as ordinary underline    */
    111         private const byte CFU_UNDERLINEDOTTED = 0x00000004;
    112         private const byte CFU_UNDERLINEDASH = 0x00000005;
    113         private const byte CFU_UNDERLINEDASHDOT = 0x00000006;
    114         private const byte CFU_UNDERLINEDASHDOTDOT = 0x00000007;
    115         private const byte CFU_UNDERLINEWAVE = 0x00000008;
    116         private const byte CFU_UNDERLINETHICK = 0x00000009;
    117         private const byte CFU_UNDERLINEHAIRLINE = 0x0000000A; /* (*) displayed as ordinary underline    */
    118 
    119         #endregion
    120 
    121         #endregion
    122      
    123 
    124         public ChatRichTextBox()
    125             : base()
    126         {
    127             base.BorderStyle = BorderStyle.FixedSingle;
    128             this.DetectUrls = false;
    129         }
    130 
    131         public Dictionary<int, REOBJECT> OleObjectList
    132         {
    133             get
    134             {
    135                 if (_oleObjectList == null)
    136                 {
    137                     _oleObjectList = new Dictionary<int, REOBJECT>(10);
    138                 }
    139                 return _oleObjectList;
    140             }
    141         }
    142 
    143         internal RichEditOle RichEditOle
    144         {
    145             get
    146             {
    147                 if (ole == null)
    148                 {
    149                     if (base.IsHandleCreated)
    150                     {
    151                         ole = new RichEditOle(this);
    152                     }
    153                 }
    154 
    155                 return ole;
    156             }
    157         }
    158 
    159         public bool InsertImageUseImageOle(string path)
    160         {
    161             try
    162             {
    163                 IGifAnimator gif = new GifAnimatorClass();
    164                 gif.LoadFromFile(path);
    165                 gif.TriggerFrameChange();
    166                 if (gif is IOleObject)
    167                 {
    168                     int index = _index ++;
    169                     REOBJECT reObj = RichEditOle.InsertOleObject(
    170                         (IOleObject)gif,
    171                         index);
    172                     RichEditOle.UpdateObjects(reObj.cp);
    173                     OleObjectList.Add(index, reObj);
    174                     return true;
    175                 }
    176                 return false;
    177             }
    178             catch (Exception)
    179             {
    180                 return false;
    181             }
    182         }
    183 
    184         public bool InsertImageUseDynamic(string path)
    185         {
    186             try
    187             {
    188                 IDynamicGif gif = new DynamicGifClass();
    189                 gif.LoadFromFile(path);
    190                 gif.Play();
    191                 if (gif is IOleObject)
    192                 {
    193                     int index = _index++;
    194                     REOBJECT reObj = RichEditOle.InsertOleObject(
    195                         (IOleObject)gif,
    196                         index);
    197                     RichEditOle.UpdateObjects(reObj.cp);
    198                     OleObjectList.Add(index, reObj);
    199                     return true;
    200                 }
    201                 return false;
    202             }
    203             catch (Exception)
    204             {
    205                 return false;
    206             }
    207         }
    208 
    209         public bool InsertImageUseGifBox(Image path)
    210         {
    211             try
    212             {
    213                 GifBox gif = new GifBox();
    214                 gif.BackColor = base.BackColor;
    215                 gif.Image = path;
    216                 RichEditOle.InsertControl(gif);
    217                 return true;
    218             }
    219             catch (Exception)
    220             {
    221                 return false;
    222             }
    223         }
    224 
    225         public bool InsertImageUseGifBox(string path)
    226         {
    227             try
    228             {
    229                 GifBox gif = new GifBox();
    230                 gif.BackColor = base.BackColor;
    231                 gif.Image = Image.FromFile(path);
    232                 RichEditOle.InsertControl(gif);
    233                 return true;
    234             }
    235             catch (Exception)
    236             {
    237                 return false;
    238             }
    239         }
    240 
    241         [DefaultValue(false)]
    242         public new bool DetectUrls
    243         {
    244             get { return base.DetectUrls; }
    245             set { base.DetectUrls = value; }
    246         }
    247 
    248         /// <summary>
    249         /// Insert a given text as a link into the RichTextBox at the current insert position.
    250         /// </summary>
    251         /// <param name="text">Text to be inserted</param>
    252         public void InsertLink(string text)
    253         {
    254             InsertLink(text, this.SelectionStart);
    255         }
    256 
    257         /// <summary>
    258         /// Insert a given text at a given position as a link. 
    259         /// </summary>
    260         /// <param name="text">Text to be inserted</param>
    261         /// <param name="position">Insert position</param>
    262         public void InsertLink(string text, int position)
    263         {
    264             if (position < 0 || position > this.Text.Length)
    265                 throw new ArgumentOutOfRangeException("position");
    266 
    267             this.SelectionStart = position;
    268             this.SelectedText = text;
    269             this.Select(position, text.Length);
    270             this.SetSelectionLink(true);
    271             this.Select(position + text.Length, 0);
    272         }
    273 
    274         /// <summary>
    275         /// Insert a given text at at the current input position as a link.
    276         /// The link text is followed by a hash (#) and the given hyperlink text, both of
    277         /// them invisible.
    278         /// When clicked on, the whole link text and hyperlink string are given in the
    279         /// LinkClickedEventArgs.
    280         /// </summary>
    281         /// <param name="text">Text to be inserted</param>
    282         /// <param name="hyperlink">Invisible hyperlink string to be inserted</param>
    283         public void InsertLink(string text, string hyperlink)
    284         {
    285             InsertLink(text, hyperlink, this.SelectionStart);
    286         }
    287 
    288         /// <summary>
    289         /// Insert a given text at a given position as a link. The link text is followed by
    290         /// a hash (#) and the given hyperlink text, both of them invisible.
    291         /// When clicked on, the whole link text and hyperlink string are given in the
    292         /// LinkClickedEventArgs.
    293         /// </summary>
    294         /// <param name="text">Text to be inserted</param>
    295         /// <param name="hyperlink">Invisible hyperlink string to be inserted</param>
    296         /// <param name="position">Insert position</param>
    297         public void InsertLink(string text, string hyperlink, int position)
    298         {
    299             if (position < 0 || position > this.Text.Length)
    300                 throw new ArgumentOutOfRangeException("position");
    301 
    302             this.SelectionStart = position;
    303             //this.SelectedRtf = @"{
    tf1ansi "+text+@"v #"+hyperlink+@"v0}";// 只能显示英文
    304             this.SelectedRtf = @"{
    tf1ansicpg936 " + text + @"v #" + hyperlink + @"v0}";  // 可以显示中文
    305             this.Select(position, text.Length + hyperlink.Length + 1);
    306             this.SetSelectionLink(true);
    307             this.Select(position + text.Length + hyperlink.Length + 1, 0);
    308         }
    309 
    310         /// <summary>
    311         /// Set the current selection's link style
    312         /// </summary>
    313         /// <param name="link">true: set link style, false: clear link style</param>
    314         public void SetSelectionLink(bool link)
    315         {
    316             SetSelectionStyle(CFM_LINK, link ? CFE_LINK : 0);
    317         }
    318         /// <summary>
    319         /// Get the link style for the current selection
    320         /// </summary>
    321         /// <returns>0: link style not set, 1: link style set, -1: mixed</returns>
    322         public int GetSelectionLink()
    323         {
    324             return GetSelectionStyle(CFM_LINK, CFE_LINK);
    325         }
    326 
    327 
    328         private void SetSelectionStyle(UInt32 mask, UInt32 effect)
    329         {
    330             CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
    331             cf.cbSize = (UInt32)Marshal.SizeOf(cf);
    332             cf.dwMask = mask;
    333             cf.dwEffects = effect;
    334 
    335             IntPtr wpar = new IntPtr(SCF_SELECTION);
    336             IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
    337             Marshal.StructureToPtr(cf, lpar, false);
    338 
    339             IntPtr res = SendMessage(Handle, EM_SETCHARFORMAT, wpar, lpar);
    340 
    341             Marshal.FreeCoTaskMem(lpar);
    342         }
    343 
    344         private int GetSelectionStyle(UInt32 mask, UInt32 effect)
    345         {
    346             CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
    347             cf.cbSize = (UInt32)Marshal.SizeOf(cf);
    348             cf.szFaceName = new char[32];
    349 
    350             IntPtr wpar = new IntPtr(SCF_SELECTION);
    351             IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
    352             Marshal.StructureToPtr(cf, lpar, false);
    353 
    354             IntPtr res = SendMessage(Handle, EM_GETCHARFORMAT, wpar, lpar);
    355 
    356             cf = (CHARFORMAT2_STRUCT)Marshal.PtrToStructure(lpar, typeof(CHARFORMAT2_STRUCT));
    357 
    358             int state;
    359             // dwMask holds the information which properties are consistent throughout the selection:
    360             if ((cf.dwMask & mask) == mask)
    361             {
    362                 if ((cf.dwEffects & effect) == effect)
    363                     state = 1;
    364                 else
    365                     state = 0;
    366             }
    367             else
    368             {
    369                 state = -1;
    370             }
    371 
    372             Marshal.FreeCoTaskMem(lpar);
    373             return state;
    374         }
    375         ///////////////////////////////////////////
    376         /////////////////////////////////////////////
    377 
    378         IRichEditOle richEditOle
    379         {
    380             get
    381             {
    382                 if (this._richEditOle == null)
    383                 {
    384                     IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
    385                     IntPtr richEditOleIntPtr = IntPtr.Zero;
    386                     Marshal.WriteIntPtr(ptr, IntPtr.Zero);
    387                     try
    388                     {
    389                         int msgResult = (int)SendMessage(this.Handle, EmotionPanel.NativeMethods.EM_GETOLEINTERFACE, IntPtr.Zero, ptr);
    390                         if (msgResult != 0)
    391                         {
    392                             IntPtr intPtr = Marshal.ReadIntPtr(ptr);
    393                             try
    394                             {
    395                                 if (intPtr != IntPtr.Zero)
    396                                 {
    397                                     Guid guid = new Guid("00020D00-0000-0000-c000-000000000046");
    398                                     Marshal.QueryInterface(intPtr, ref guid, out richEditOleIntPtr);
    399 
    400                                     this._richEditOle = (IRichEditOle)Marshal.GetTypedObjectForIUnknown(richEditOleIntPtr, typeof(IRichEditOle));
    401                                 }
    402                             }
    403                             finally
    404                             {
    405                                 Marshal.Release(intPtr);
    406                             }
    407                         }
    408                     }
    409                     catch (Exception err)
    410                     {
    411                         Trace.WriteLine(err.ToString());
    412                     }
    413                     finally
    414                     {
    415                         Marshal.FreeCoTaskMem(ptr);
    416                     }
    417                 }
    418                 return this._richEditOle;
    419             }
    420         }
    421 
    422         public new bool ReadOnly { get; set; }
    423 
    424         protected override void WndProc(ref Message m)
    425         {
    426             switch (m.Msg)
    427             {
    428                 case 0x0100:
    429                     if (this.ReadOnly)
    430                         return;
    431                     break;
    432                 case 0X0102:
    433                     if (this.ReadOnly)
    434                         return;
    435                     break;
    436                 default:
    437                     break;
    438             }
    439             base.WndProc(ref m);
    440         }
    441 
    442         List<MyGIF> gifList = new List<MyGIF>();
    443         Panel gifPanel = new Panel();
    444         public void ClearGif()
    445         {
    446             this.gifPanel.Controls.Clear();
    447             this.gifList.Clear();
    448         }
    449 
    450         public void InsertGIF(string Name, Image Data)
    451         {
    452 
    453             MyGIF gif = new MyGIF(Name, Data);
    454             gif.Box.Invalidate();
    455             this.gifPanel.Controls.Add(gif.Box);
    456             this.gifList.Add(gif);
    457 
    458             //RichEditOle ole = new RichEditOle(this);
    459             ole.InsertControl(gif);
    460 
    461 
    462             this.Invalidate();
    463 
    464 
    465         }
    466 
    467         public string GetGIFInfo()
    468         {
    469             string imageInfo = "";
    470             REOBJECT reObject = new REOBJECT();
    471             for (int i = 0; i < this.richEditOle.GetObjectCount(); i++)
    472             {
    473                 this.richEditOle.GetObject(i, reObject, GETOBJECTOPTIONS.REO_GETOBJ_ALL_INTERFACES);
    474                 MyGIF gif = this.gifList.Find(p => p != null && p.Index == reObject.dwUser);
    475                 if (gif != null)
    476                 {
    477                     imageInfo += reObject.cp.ToString() + ":" + gif.Name + "|";
    478                 }
    479             }
    480             return imageInfo;
    481         }
    482 
    483         private void SetSelectionStyle()
    484         {
    485             CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
    486             cf.cbSize = (UInt32)Marshal.SizeOf(cf);
    487             cf.dwMask = CFM_LINK;
    488             cf.dwEffects = CFE_LINK;
    489 
    490             IntPtr wpar = new IntPtr(SCF_SELECTION);
    491             IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
    492             Marshal.StructureToPtr(cf, lpar, false);
    493 
    494             IntPtr res = (IntPtr)SendMessage(Handle, EM_SETCHARFORMAT, wpar, lpar);
    495 
    496             Marshal.FreeCoTaskMem(lpar);
    497         }
    498 
    499         public void SetFont(string Name, bool Bold, bool Italic, bool Underline, Color Color, float Size)
    500         {
    501             FontStyle style = FontStyle.Regular;
    502             if (Bold) style |= FontStyle.Bold;
    503             if (Italic) style |= FontStyle.Italic;
    504             if (Underline) style |= FontStyle.Underline;
    505 
    506             this.Font = new Font(Name, Size, style);
    507             this.ForeColor = Color;
    508         }
    509 
    510         public string GetTextToSend()
    511         {
    512             string value = string.Empty;
    513             value += "\n" + this.Font.Name;
    514             value += "\b" + (this.Font.Bold ? "1" : "0");
    515             value += "\i" + (this.Font.Italic ? "1" : "0");
    516             value += "\u" + (this.Font.Underline ? "1" : "0");
    517             value += "\s" + this.Font.Size.ToString();
    518             value += "\c" + ColorTranslator.ToHtml(this.ForeColor);
    519             value += "\t" + this.Text;
    520             value += "\p" + this.GetGIFInfo();
    521 
    522             return value;
    523         }
    524     }
    525 }
  • 相关阅读:
    穆僮电脑小课堂
    PMON
    mmcm 和pll
    手把手教你完成第一个vivado项目
    Vivado的helloword程序:软件工程部分
    Vivado的helloword程序:硬件工程部分
    让 Vivado有Zybo Board的配置文件
    vivado笔记
    Spartan6上软核系统自定义外设调用AXI Stream FFT经验
    网站目录下多出的 core 文件
  • 原文地址:https://www.cnblogs.com/endv/p/6158177.html
Copyright © 2020-2023  润新知