RichTextBox中如何添加gif的图片呢? 做类似QQ聊天的东西。

air123456789 2013-07-26 03:34:32
在网上找到了个可以贴gif图进去的,但是无法读取出来,有的又不会动, 想找个实用的。。
不关要能显示gif,而且还需要能读取的出来复制到其他的richtextbox里。
...全文
371 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
hyblusea 2013-07-31
  • 打赏
  • 举报
回复
引用 26 楼 air123456789 的回复:
引用 25 楼 hyblusea 的回复:
[quote=引用 24 楼 air123456789 的回复:] [quote=引用 23 楼 hyblusea 的回复:] 这是效果,需要选择第三种方式:GifBox
9楼的那个网站,我刚下载是个logon.aspx的东西,然后登录了,下载下来,解压就提示我文件损坏,这是何故?而现在,那个地址已经变成了一个视频程序的连接了!
你的电脑太神奇了, 连接仍然是有效的 我本地也有源码, 需要的话留个你的邮箱。[/quote] 好了,我下载到源码了,可是如何复制出来呢? 发送的时候获取不到图片也没用吖。[/quote] 可以肯定的是绝对能够获取到图片, 但,这需要仔细看看 8楼代码中的  GetGIFInfo()方法, 首先通过 richEditOle.GetObjectCount()获得RichtextBox中Ole控件的数量,再循环执行 richEditOle.GetObject()挨个获取详细的Ole控件信息, 他的返回值是一个结构:

public class REOBJECT
    {
        public int cbStruct = Marshal.SizeOf(typeof(REOBJECT));	// Size of structure
        public int cp;											// Character position of object
        public Guid clsid;										// Class ID of object
        public IntPtr poleobj;								// OLE object interface
        public IStorage pstg;									// Associated storage interface
        public IOleClientSite polesite;							// Associated client site interface
        public Size sizel;										// Size of object (may be 0,0)
        public uint dvAspect;									// Display aspect to use
        public uint dwFlags;									// Object status flags
        public uint dwUser;										// Dword for user's use
    }
包含了丰富的信息,其中CP属性描述当前Ole位于RichtextBox中的位置(他是动态的,会因为实际位置改变而自动变化 ), poleobj 属性则是一个指针,指向你的图片控件, 是你InsertControl()时插入的控件, 如果插入的是GifBox,可以使用以下代码转换: GifBox ibx = Marshal.GetObjectForIUnknown(REOBJECT.poleobj) as GifBox; 获取到了图片位置,以及图片,剩下的就是如何将他们告诉给接收者了。
air123456789 2013-07-31
  • 打赏
  • 举报
回复
引用 25 楼 hyblusea 的回复:
[quote=引用 24 楼 air123456789 的回复:] [quote=引用 23 楼 hyblusea 的回复:] 这是效果,需要选择第三种方式:GifBox
9楼的那个网站,我刚下载是个logon.aspx的东西,然后登录了,下载下来,解压就提示我文件损坏,这是何故?而现在,那个地址已经变成了一个视频程序的连接了![/quote] 你的电脑太神奇了, 连接仍然是有效的 我本地也有源码, 需要的话留个你的邮箱。[/quote] 好了,我下载到源码了,可是如何复制出来呢? 发送的时候获取不到图片也没用吖。
hyblusea 2013-07-31
  • 打赏
  • 举报
回复
引用 24 楼 air123456789 的回复:
[quote=引用 23 楼 hyblusea 的回复:] 这是效果,需要选择第三种方式:GifBox
9楼的那个网站,我刚下载是个logon.aspx的东西,然后登录了,下载下来,解压就提示我文件损坏,这是何故?而现在,那个地址已经变成了一个视频程序的连接了![/quote] 你的电脑太神奇了, 连接仍然是有效的 我本地也有源码, 需要的话留个你的邮箱。
air123456789 2013-07-31
  • 打赏
  • 举报
回复
引用 23 楼 hyblusea 的回复:
这是效果,需要选择第三种方式:GifBox
9楼的那个网站,我刚下载是个logon.aspx的东西,然后登录了,下载下来,解压就提示我文件损坏,这是何故?而现在,那个地址已经变成了一个视频程序的连接了!
hyblusea 2013-07-31
  • 打赏
  • 举报
回复

这是效果,需要选择第三种方式:GifBox
hyblusea 2013-07-31
  • 打赏
  • 举报
回复
留下你的邮箱,我给你发源码
hyblusea 2013-07-31
  • 打赏
  • 举报
回复
引用 20 楼 air123456789 的回复:
欢迎大家踊跃参加回答问题。
还没解决? 9楼给你的链接2,不是你想要的??
air123456789 2013-07-31
  • 打赏
  • 举报
回复
欢迎大家踊跃参加回答问题。
air123456789 2013-07-30
  • 打赏
  • 举报
回复
引用 18 楼 benbenRH 的回复:
WebBrowser可以做编辑器的 如果是VS自带的WebBrowser控件,有一个MODE的标识的,只要设置为EditMode就是编辑模式了! 更简单的方法是: 在html的body里添加contenteditable="true"属性 如
<html><head><title>example</title></head><body contenteditable="true"> 这里是可以编辑的</body> </html>
是winform吖,
请叫我卷福 2013-07-29
  • 打赏
  • 举报
回复
复制 粘贴的话 楼主可以修改源码中的 List<MetaInfo> ControlList = new List<MetaInfo>(); 为public 就可以获取当前richtextbox中所有已插入的控件 找到对应的picturebox 复制其中的image 粘贴的时候 再用image生成一个picturebox插入到另外一个richtextbox中
请叫我卷福 2013-07-29
  • 打赏
  • 举报
回复
向richtextbox中插入一个picturebox控件 控件中放置gif 可以插入任何control http://www.codeproject.com/Articles/134358/TRichTextBox-A-universal-RichTextBox-which-can-dis
  • 打赏
  • 举报
回复
看看 2013年07月29日→星座:狮子座 癸巳〖蛇〗己未月丙申日甲午时 二〇一三年六月廿二 今属:火;五行:水火土金木;缺:; 纳音五行:长流水。
mingcsharp 2013-07-29
  • 打赏
  • 举报
回复
hyblusea 2013-07-29
  • 打赏
  • 举报
回复
其中IRichEditOle接口中的 InsertControl(),是将一个 Gif插入到 RichTextbox中, GetGIFInfo(), 用于返回RichTextBox中所有的ole对象。 更详细的请参考: 1.将播放器插入到RichTextBox: http://www.codeproject.com/Articles/4528/Use-IRichEditOle-from-C 2.(推荐):http://www.csharpwin.com/csharpresource/2667.shtml 他所介绍的3种方法,均基于Ole, ole控件的实现方法一个来源于腾讯,一个来源于飞信,第三个是作者自己实现的类,前两个我测试失败,第三种方法推荐参考 。
hyblusea 2013-07-29
  • 打赏
  • 举报
回复
如果要在RichTextbox中插入Gif, 只有一种方法, 那就是 IRichEditOle,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.ComponentModel;

namespace ControlLib
{
    public class RichTextBoxEx : RichTextBox
    {
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern int SendMessage(IntPtr hWnd, int message, IntPtr wParam, IntPtr lParam);
        [DllImport("User32.dll", CharSet = CharSet.Auto, PreserveSig = false)]
        internal static extern IRichEditOle SendMessage(IntPtr hWnd, int message, int wParam);

        [StructLayout(LayoutKind.Sequential)]
        private 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;
            public int lcid;
            public int dwReserved;
            public Int16 sStyle;
            public Int16 wKerning;
            public byte bUnderlineType;
            public byte bAnimation;
            public byte bRevAuthor;
            public byte bReserved1;
        }

        private const int WM_USER = 0x0400;
        private const int EM_GETCHARFORMAT = WM_USER + 58;
        private const int EM_SETCHARFORMAT = WM_USER + 68;
        private const int SCF_SELECTION = 0x0001;
        private const UInt32 CFE_LINK = 0x0020;
        private const UInt32 CFM_LINK = 0x00000020;


        IRichEditOle _richEditOle = null;
        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 = SendMessage(this.Handle, RichEditOle.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;
            }
        }

        class RichEditOle
        {
            [DllImport("ole32.dll", PreserveSig = false)]
            static extern int CreateILockBytesOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease, [Out] out ILockBytes ppLkbyt);
            [DllImport("ole32.dll")]
            static extern int StgCreateDocfileOnILockBytes(ILockBytes plkbyt, uint grfMode, uint reserved, out IStorage ppstgOpen);

            public const int EM_GETOLEINTERFACE = 0x0400 + 60;

            private RichTextBoxEx richTextBox;
            private IRichEditOle ole;

            internal RichEditOle(RichTextBoxEx richEdit)
            {
                this.richTextBox = richEdit;
                this.ole = SendMessage(this.richTextBox.Handle, EM_GETOLEINTERFACE, 0);
            }

            internal void InsertControl(Control ctrl)
            {
                if (ctrl == null)
                    return;

                Guid guid = Marshal.GenerateGuidForType(ctrl.GetType());

                ILockBytes lockBytes;
                CreateILockBytesOnHGlobal(IntPtr.Zero, true, out lockBytes);

                IStorage storage;
                StgCreateDocfileOnILockBytes(lockBytes, (uint)(STGM.STGM_SHARE_EXCLUSIVE | STGM.STGM_CREATE | STGM.STGM_READWRITE), 0, out storage);

                IOleClientSite oleClientSite;
                this.ole.GetClientSite(out oleClientSite);

                REOBJECT reObject = new REOBJECT()
                {
                    cp = this.richTextBox.SelectionStart,
                    clsid = guid,
                    pstg = storage,
                    poleobj = Marshal.GetIUnknownForObject(ctrl),
                    polesite = oleClientSite,
                    dvAspect = (uint)(DVASPECT.DVASPECT_CONTENT),
                    dwFlags = (uint)0x00000002,
                };

                try
                {
                    reObject.dwUser = 1;
                }
                catch { }

                this.ole.InsertObject(reObject);

                Marshal.ReleaseComObject(lockBytes);
                Marshal.ReleaseComObject(oleClientSite);
                Marshal.ReleaseComObject(storage);
            }
        }


        public RichTextBoxEx()
            : base()
        {
            base.BorderStyle = BorderStyle.FixedSingle;
            this.DetectUrls = false;
        }

        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();

        [DefaultValue(false)]
        public new bool DetectUrls
        {
            get { return base.DetectUrls; }
            set { base.DetectUrls = value; }
        }

        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 void InsertControl(Control ctrl)
        {
            this.gifPanel.Controls.Add(ctrl);
            RichEditOle ole = new RichEditOle(this);
            ole.InsertControl(ctrl);

            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;
        }

    }
}

air123456789 2013-07-29
  • 打赏
  • 举报
回复
欢迎大家踊跃参加回答问题。
benbenRH 2013-07-29
  • 打赏
  • 举报
回复
WebBrowser可以做编辑器的 如果是VS自带的WebBrowser控件,有一个MODE的标识的,只要设置为EditMode就是编辑模式了! 更简单的方法是: 在html的body里添加contenteditable="true"属性 如
<html><head><title>example</title></head><body contenteditable="true"> 这里是可以编辑的</body> </html>
请叫我卷福 2013-07-29
  • 打赏
  • 举报
回复
如果要向.net中自带的RichTextbox控件插入动态图 都得自己稍作处理 默认不支持 网上别人实现的方法都比较麻烦
air123456789 2013-07-29
  • 打赏
  • 举报
回复
引用 12 楼 xiaozhi_5638 的回复:
向richtextbox中插入一个picturebox控件 控件中放置gif 可以插入任何control http://www.codeproject.com/Articles/134358/TRichTextBox-A-universal-RichTextBox-which-can-dis
为嘛我这个网站下载的.zip文件 点解压都是说已经损坏了?
air123456789 2013-07-29
  • 打赏
  • 举报
回复
引用 13 楼 xiaozhi_5638 的回复:
复制 粘贴的话 楼主可以修改源码中的 List<MetaInfo> ControlList = new List<MetaInfo>(); 为public 就可以获取当前richtextbox中所有已插入的控件 找到对应的picturebox 复制其中的image 粘贴的时候 再用image生成一个picturebox插入到另外一个richtextbox中
很麻烦的样子,但是读出来的时候怕顺序不一样,以为你 panel1.Controls 读出来的,和控件里的排列顺序又不同。
加载更多回复(7)

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧