NET RichTextBox控件如何可以插入图像
本文介绍。NET RichTextBox控件如何可以插入图像,控制和ActiveX对象通过使用OLE方式,如在解释,。不幸的是,它涵盖了只用一个C源代码样本,所以我需要在托管代码(C#)实施类似的解决方案。
有一个RichTextBox插入图片和OLE对象的其他有关条款,但他们使用的是RTF代码,我需要一个更适合聊天使用专门的控制,并提供了一种方法插入表情符号,进度条和图像,最后,恢复他们得到他们的OLE处理或任何对象的属性。特别感谢
Khendys戈登的文章:""。背景
要实现的解决方案,我需要使用的P / Invoke平台调用方法。我从大量的信息。
插入RichTextBox的OLE对象的第一步是得到它IRichEditOle的接口。它可以做,通过发送消息EM_GETOLEINTERFACE控制:this.IRichEditOle = SendMessage消息(richEditHandle,EM_GETOLEINTERFACE,0);
有了这个接口,你可以通过REOBJECT结构中插入的对象。重要的是要注意您可以指定插入点,纵横dwUser变量来存储此对象的标志或任何相关的信息,因此你可以在任何时间更新恢复它.//------- ----------------REOBJECT reoObject =新REOBJECT();reoObject.cp = this._richEdit.TextLength;reoObject.clsid = GUID;reoObject.pstg = pStorage;reoObject.poleobj = Marshal.GetIUnknownForObject(对照组);reoObject.polesite = pOleClientSite;reoObject.dvAspect =(UINT)(DVASPECT.DVASPECT_CONTENT);reoObject.dwFlags =(UINT)(REOOBJECTFLAGS.REO_BELOWBASELINE);reoObject.dwUser = 1; this.IRicEditOle.InsertObject(reoObject);//-----------------------
插入图像,你需要实现接口IDataObject的,在这种情况下,我命名它myDataObject。这个类是一个OLE回调对象使用FORMATETC和STGMEDIUM结构,展示形象,告诉OLE容器,这个对象是一个GDI中位图的剪贴板格式(CF_BITMAP)(TYMED_GDI)公共类myDataObject:IDataObject的。{ 私营位图mBitmap; 公众的FORMATETC mpFormatetc; #地区的IDataObject议员 私人常量UINT S_OK = 0; 私人常量UINT E_POINTER = 0x80004003; 私人常量UINT E_NOTIMPL = 0x80004001; 私人常量UINT的E_FAIL = 0X80004005; ; 公共UINT的GetData(文献的FORMATETC pFormatetc &# 160; 文献的STGMEDIUM pMedium) { IntPtr的hDst = mBitmap.GetHbitmap(); pMedium.tymed =(INT)TYMED.TYMED_GDI; pMedium.unionmember = hDst; pMedium.pUnkForRelease = IntPtr.Zero; (UINT)返回S_OK; } ... ... #endregion 公共myDataObject() { mBitmap =新的Bitmap(16,16); mpFormatetc =新的FORMATETC(); } 公共无效SetImage(字符串strFilename) { 尝试 ; { mBitmap =(位图)Bitmap.FromFile(strFilename,TRUE); ; / /剪贴板格式= CF_BITMAP & #160; mpFormatetc.cfFormat = CLIPFORMAT.CF_BITMAP; / /目标设备=屏幕 0; mpFormatetc.ptd = IntPtr.Zero; & #160; / /详细程度=全部内容 ; mpFormatetc.dwAspect = DVASPECT.DVASPECT_CONTENT; / /指数= applicaple & #160; mpFormatetc.lindex = -1; 0; / /存储介质的HBITMAP处理 60; mpFormatetc.tymed = TYMED.TYMED_GDI; } 捕获 { } } 公共无效SetImage(Image图像) { 尝试 0; { mBitmap =新的位图(图片); / /剪贴板格式= CF_BITMAP mpFormatetc.cfFormat = CLIPFORMAT.CF_BITMAP; 0; / /目标设备=屏幕 &# 160;mpFormatetc.ptd = IntPtr.Zero; ; / /详细程度=全部内容 60;mpFormatetc.dwAspect = DVASPECT.DVASPECT_CONTENT; 0; / /指数= applicaple ; mpFormatetc.lindex = -1; &# 160; / /存储介质的HBITMAP处理 & #160; mpFormatetc.tymed = TYMED.TYMED_GDI; 0; } 捕获 { 0; } }}
看一个成员方法SetImage如何创建一个Bitmap对象,利用其处理时调用的GetData。
现在,这里的对象是如何创建一个共享的全局内存和指针(IStorage)和使用IRichEditOle.public无效InsertMyDataObject(myDataObject MDO)OleClientSite接口插入到RichEditBox{ (MDO == NULL) 60; 回报; //----------------------- ILockBytes pLockBytes; INT SC = CreateILockBytesOnHGlobal(IntPtr.Zero, ; 真实的,出pLockBytes); IStorage pStorage; SC = StgCreateDocfileOnILockBytes(pLockBytes,(UINT) (STGM.STGM_SHARE_EXCLUSIVE | STGM.STGM_CREATE | &# 160; STGM.STGM_READWRITE) 0,pStorage); 的IOleClientSite pOleClientSite; 60; this.IRichEditOle.GetClientSite(出pOleClientSite); 0; //----------------------- GUID(GUID = Marshal.GenerateGuidForType mdo.GetType()); GUID IID_IOleObject = 新的Guid("{00000112 - 0000 - 0000 - C000 - 000000000046}"); GUID IID_IDataObject = &# 160; 新的Guid("{0000010e - 0000 - 0000 - C000 - 000000000046}"); GUID IID_IUnknown = 新的Guid("{00000000 - 0000 - 0000 - C000 - 000000000046}"); 对象pOleObject; INT HR = OleCreateStaticFromData(MDO,楼盘IID_IOleObject (UINT)OLERENDER.OLERENDER_FORMAT,文献mdo.mpFormatetc pOleClientSite,pStorage出pOleObject); 如果(pOleObject == NULL) 回报; //----------------------- //----------------------- OleSetContainedObject(pOleObject,TRUE);&# 160; REOBJECT reoObject =新REOBJECT(); reoObject.cp = this._richEdit.TextLength; reoObject.clsid = GUID; reoObject.pstg = pStorage; reoObject.poleobj = Marshal.GetIUnknownForObject(pOleObject); 60; reoObject.polesite = pOleClientSite; reoObject.dvAspect =(UINT)(DVASPECT.DVASPECT_CONTENT); reoObject.dwFlags =(UINT)(REOOBJECTFLAGS.REO_BELOWBASELINE); &# 160;reoObject.dwUser = 0; this.IRichEditOle.InsertObject(reoObject); //----------------------- &# 160;//----------------------- Marshal.ReleaseComObject(pLockBytes); Marshal.ReleaseComObject(pOleClientSite); Marshal.ReleaseComObject(pStorage); Marshal.ReleaseComObject(pOleObject); //-----------------------
还有其他的方法来插入控件和ActiveX对象,他们看起来非常相似,上面的方法,所以请查看源代码。兴趣点
最后,如何控制更新?
这是诡计,你需要使用一个计时器,并调用该方法UpdateObjects。此方法执行搜索RichTextBox中的所有对象,如果他们作为特殊标记(在我来说,我使用的dwUser变量),他们将被更新:公共无效UpdateObjects(){ K = this.IRichEditOle.GetObjectCount(); 为(int i = 0;我LT; K,I) { & #160; REOBJECT reoObject =新REOBJECT(); this.IRichEditOle.GetObject(I,reoObject ; GETOBJECTOPTIONS.REO_GETOBJ_ALL_INTERFACES); (reoObject.dwUser == 1) &# 160; { 点PT = this._richEdit.GetPositionFromCharIndex(reoObject.cp); 0; 矩形RECT =新的Rectangle(PT,reoObject.sizel); this._richEdit.Invalidate(RECT,FALSE); / /重绘 } }}
有很多优化这种控制,但现在需要的工作,任何建议表示赞赏。使用代码
要使用的代码,只需添加一个引用的控制,投入正常的RichTextBox的形式,然后更换MyExtRichTextBox类型:MyExtRichTextBox.MyExtRichTextBox richTextBox1的;提示
我通过创建一个控件(按钮和进度条)的阵列,并加入一个计时器的形式,然后调用这样的方法UpdateObjects更新的对象为:private void timer1_Tick(对象发件人,发送System.EventArgs){ 为(int i = 0;我LT; ar.Count;我) { itimer的; ; 如果(itimer的GT 100) 60; itimer的= 0; 对象obj = AR [我]; 60; 如果(obj是按钮) { & #160; BT =按钮(Button)的OBJ; 0; (bt.Text ="Clickedquot;) & #160; bt.Text ="按钮quot; i.ToString() &# 160; " - "itimer.ToString(); } 其他 & #160; { ProgressBar的PB =(进度条)OBJ; 如果(1 pb.Value GT 100) pb.Value = 0; pb.Value = pb.Value 1; } } richTextBox1.UpdateObjects();}历史版本1.0 - 1 / 2005年11月
NET RichTextBox控件如何可以插入图像的更多相关文章
- 在RichTextBox控件中插入图片
. 在RichTextBox控件中插入图片 关键点 . 实现过程 . public void ShowInsertImageDlg() { OpenFileDialog OpenFileD ...
- RichTextBox控件-主要用于输入输出编辑文本信息
1.在RichTextBox控件中添加超链接文字 private void btn_Add_Click(object sender, EventArgs e) { rtbox_HyperLink.Ap ...
- 在RichTextBox控件中添加图片和文字
public void SetText(RichTextBox rtb) { rtb.Text = "在RichTextBox控件中添加图片和文字" + Environment.N ...
- 设置RichTextBox控件的文本的对齐方式
实现效果: 知识运用: RichTextBox控件的SelectionAlignment属性 //获取或设置在当前选择或插入点的对齐方式 public HorizontalAlignment Sele ...
- (C#)RichTextBox控件
RichTextBox(有格式文本)控件可实现TextBox控件的所有功能. ❶在RichTextBox控件中显示滚动条 RichTextBox可设置Multiline属性来控制是否显示滚动套,tru ...
- RichTextBox控件日常使用集合
1.RichTextBox控件自动滚动到底部 richTextBox1.ScrollToCaret(); //将控件的内容滚动到当前光标位置
- vc 在edit控件中动态插入数据滚动显示
内存从网上论坛摘抄整理 思路:给控件设置多行属性,设置垂直滚动条,Auto Vscroll设置为true,放入文本后把插入点设置到末尾 pEdit->LineScroll(pEdit->G ...
- C#超简单方法实现两个richtextbox控件滚动条同步滚动
此文章属于作者原创,转载请注明,谢谢 有时候我们需要实现对照文章等,往往将文本放到两个richtextbox控件中,但是,如果我们需要同步滚动查看,来达到更好的观看效果. 当然,传统的方法重载控件或者 ...
- HOW TO:使用 Visual C# .NET 打印 RichTextBox 控件的内容
概要 本分步指南介绍了如何打印 RichTextBox 控件的内容.RichTextBox 控件没有提供任何打印 RichTextBox 内容的方法.您可以扩展 RichTextBox 类以使用 EM ...
随机推荐
- 可在广域网部署运行的QQ高仿版 -- GG叽叽V3.2,增加离线消息、离线文件功能(源码)
(几句题外话:虽然就如何将GG发展为一个有商业价值的产品,我还没有很清晰明确的思路,但是从GG发布以来,通过GG认识了一些朋友,也接了一些小单子,赚了一点小钱.有了一点甜头,目前和2.3个好朋友一起做 ...
- Jquery Mobile 小结
第一次做一个移动站点,当时纠结选Jquery Mobile还是Zepto,Zepto相对于JM更加轻巧,语法上面也很相似,但考虑到时间问题和JM自带了很多组件(Bootstrap惯出来的),还是选择了 ...
- 消息队列-rabbitMQ
消息队列两个用处:服务间解耦,缓解压力(削峰平谷),以前用过ZMQ.狼厂内部的NMQ,现在接触了java开源的kafka和RabbitMQ.目前先不求甚解,有个大概的认识. RabbitMQ的安装和入 ...
- swift 创建单例模式
一.意图 保证一个类公有一个实例,并提供一个访问它的全局访问点. 二.使用场景 1.使用场景 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时 当这个唯一实例应该是通过子类化可扩展的,并且 ...
- php版的redis操作库predis操作大全
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/146.html predis是php连接redis的操作库,由于它完全使用 ...
- Atitit.数据库存储引擎的原理与attilax 总结
Atitit.数据库存储引擎的原理与attilax 总结 1. 存储引擎是什么1 2. 其它数据库系统(包括大多数商业选择)仅支持一种类型的数据存储2 3. 表的存储有三个文件:结构+数据+索引2 4 ...
- G2 DT时代的图形语法 正式发布
G2有一个高大上的名字叫做:The Grammar Of Graphics——图形语法.它是一个强大的语义化图表生成工具,它提供了一整套图形语法,可以让用户通过简单的语法搭建出无数种图表,并且集成了大 ...
- css 用direction来改变元素水平方向,价值研究。
"direction"有两个值:ltr | rtl ltr:从左往右 rtl:从右往左 默认:ltr 一起看个效果就懂了. <style> div{ direction ...
- Android线程之并发处理
上一篇为大家介绍了关于Looper的简单知识,本篇我们介绍一下多线程的并发处理,我们知道Handler通过sendMessage()发送的消息,首先发送给了Looper,存入Looper的消息栈,之后 ...
- maven -- 学习笔记(四)实现在Eclipse用maven搭建springmvc项目(附构建步骤和详细实现代码)
Learn from:http://www.cnblogs.com/fangjins/archive/2012/05/06/2485459.html,感谢楼主的分享,才有下面的这篇学习小结 一.环境准 ...