免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6181 | 回复: 13
打印 上一主题 下一主题

[C++] win32 richedit 如何插入图片? 插入图片后去掉图片文件名 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-02-11 14:52 |只看该作者 |正序浏览
本帖最后由 mosjin 于 2014-02-11 14:57 编辑

1. 环境:
Windows, C++, vs2008, RichEdit2或者3.  win32编程(非采用MFC的方式)


2. 参照的代码:  http://msdn.microsoft.com/en-us/ ... 6%28v=vs.85%29.aspx

3.  问题:

      1). 当前通过ole的方式可以插入bmp图片.  问题是: 插入图片后,在图片的下面会有图片的文件名.   这个并不是我想要的.  如下图(图中的scroll.bmp不是我想要的)



      2). 请问:

          .如何去掉多余的文件名.(即在插入图片之后不显示图片的文件名)

          .或者: 有另外的方法插入图片.


请您 附上关键性代码.   

请您 直接回帖, 或者发给我的email: AFRL@163.com


多谢!

论坛徽章:
0
14 [报告]
发表于 2014-02-13 09:20 |只看该作者
w_anthony 发表于 2014-02-12 16:59
回复 12# mosjin

你说的ImageOleLib那些都是一个真实的或者说内置的OLE对象所提供的功能,但是我这个是 ...



谢谢您的指点!
我现在只是概念上大概理解了您的想法. 这部分具体的代码对于我来说比较有难度.
另外, 我们这儿自己的工作机不能上网, 所以可能没能及时看到您的回复并留言, 请您谅解.
如果您愿意我想留下您的联系方式, 在之后您有空时进一步请教您这个问题!


论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
13 [报告]
发表于 2014-02-12 16:59 |只看该作者
回复 12# mosjin

你说的ImageOleLib那些都是一个真实的或者说内置的OLE对象所提供的功能,但是我这个是自定义的OLE对象,通过“自绘”来显示图片的,所以几乎不可能有现成的使用于其它OLE对象的几句简单的API调用就能实现的。
但是虽然没有现成的可以用,但是要实现它的思路并不难想到。
如果说要使这个OLE对象变成一个真正动态的OLE对象,那么或许还要做很多事情,至少应该实现IRunnableObject接口。
但是如果只是要让它看起来会动,而不理会外部从OLE对象的其它接口取数据或控制的话,那么就比较容易了。
相信你也发现了实际上这个OLE对象只是在OnDrawInternal里面做了“自绘”,那么只要在合适的实机,让各桢图片连续“自绘”也就实现了GIF动态效果。
现在只需要解决以下几个问题:
1、如何取得gif图片里面不同桢的数据、各桢的时间间隔以及循环次数?
答:Gdiplus::bitmap完全可以得到这些数据,你可以MSDN它的用法。我附件的代码里面用Gdiplus::bitmap读取图片文件,但是它并不是自定义OLE对象的一部分,只是借用它得到了一个HBITMAP,然后让OLE对象拥有这个HBITMAP来进行绘图。如果要做动态绘图,那么显然这样的自定义OLE对象应该拥有一个Gdiplus::bitmap,这样它才能从中得到各桢数据。
2、如何控制各桢时间间隔?
答:API的SetTimer就可以了,控制定时总是有很多办法,我原先的代码是采用SetTimer回调函数的方式来控制时间延时,定时器溢出后桢数+1。
3、定时器溢出后如何触发它的自绘行为?
答:整体InvalidateRect当然是一个办法,但肯定不是一个好办法。最好的办法应该是只刷新自己的区域。定时器溢出后,通过IRichEditOle::GetObject遍历所有OLE对象,通过比较是否与自己的IOleObject指针相等的方式找到对应的REOBJECT,这里的REOBJECT::cp是该OLE对象的位置,通过发EM_POSFROMCHAR消息,可以得到自己的左上顶点坐标,由于本来就知道自己的宽高,通过一系列计算就可以得到自己的区域,然后用InvalidateRect仅刷新这个部分就可以触发OnDrawInternal的自绘调用。最后记得开下一桢的定时器。当然为了效率考虑,最好与RichEdit的区域取交集,如果发现没有交集,也就是不可见,那么当然可以先关了定时器让它休息一会儿,节省CPU。
4、如何自绘?
答:自绘就简单了,通过Gdiplus::bitmap和代表当前第几桢标志的变量联合起来取得当前桢的图片将其画到OnDrawInternal的HDC参数上也就完事了。如果有为效率考虑临时关定时器节省CPU的,那么这里要记得把定时器开起来。
------------------------
上面只是大致思路,细节上要做好也有很多要注意的地方,比如OnCloseInternal的时候千万记得先关定时器,否则之后再触发可能会挂;OnDrawInternal的时候只有在bMetaFile是FALSE的时候才能画,否则可能导致动画速度不太正常;选中和未选中是否要反选显示等等。

论坛徽章:
0
12 [报告]
发表于 2014-02-12 16:01 |只看该作者
w_anthony 发表于 2014-02-12 11:01
我把代码整理了下,附件里面
这个自定义的OLE对象只实现了基本的显示功能,并不包含复制粘贴的实现。
我原 ...


您的代码工作的很好!!!
我们的项目不是win32的, 是在Qt中用到richedit控件, 并向这个控件中插入(显示)图片(目前是静态的,之后可能会有动态的图片)
我是win32和gdi的新手, 刚才看了您的代码, 写的很精彩, 我大概理解了整个流程.

对于您说的加入gif图片功能, 要实现以下3个函数:
        virtual void OnCloseInternal() = 0;
        virtual void GetSizeInternal(LPSIZE psize) = 0;
        virtual void OnDrawInternal(HDC hdcDraw, LPCRECT lprcBounds, BOOL bMetaFile) = 0;

那么,请问您以下几个问题:
1. "在适合的时机作下一桢图片的绘图就行了", 在适合的时机? 如何绘下一桢图?  (我们项目中也只是显示功能, 更复杂的功能目前没有需求)
能不能大概说明一下.

2. 将Gdiplus::bitmap直接纳入其中?
我没太明白这个含义...

我查了一下资料, gif是不是需要用到:
1). ImageOleLib::IGifAnimatorPtr, 并使用它的 TriggerFrameChange() 方法?
2). 播放下一桢是否调用:
LPOLEOBJECT 的DoVerb() 方法?


多谢!





论坛徽章:
0
11 [报告]
发表于 2014-02-12 11:51 |只看该作者
w_anthony 发表于 2014-02-12 11:01
我把代码整理了下,附件里面
这个自定义的OLE对象只实现了基本的显示功能,并不包含复制粘贴的实现。
我原 ...


目前我需要解决静态显示的问题.
非常感谢,我下载来看看,不懂再请教您吧.

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
10 [报告]
发表于 2014-02-12 11:01 |只看该作者
本帖最后由 w_anthony 于 2014-02-12 11:09 编辑

我把代码整理了下,附件里面 asd.rar (5.06 KB, 下载次数: 15)
这个自定义的OLE对象只实现了基本的显示功能,并不包含复制粘贴的实现。
我原先的代码包含支持GIF动态图片插入,不过这个有点长,而且LZ可能就只需要静态的,所以删掉了。
如果需要动态的GIF,可以从COleImageBase另外继承一个,将Gdiplus::bitmap直接纳入其中,实现相应的三个纯虚函数,在适合的时机作下一桢图片的绘图就行了。
-----------------------------------
忘了说了,项目如果是多字节字符集而不是unicode,那么GetOpenFileName得到的文件名要转成unicode给Gdiplus::bitmap来打开。因为是测试代码,我这里直接偷懒了,DEBUG是unicode的,所以不需要转换,而RELEASE的我没把项目改成unicode(VS2003默认多字节),编译无法通过,你可以自己看着办吧,反正这不是关键。

论坛徽章:
0
9 [报告]
发表于 2014-02-12 10:34 |只看该作者
w_anthony 发表于 2014-02-12 08:47
这个我倒是知道,只是比较麻烦,代码量有点多
不过我不是用内置的Ole对象,而是用自定义的方式来实现的



有代码 9好,多点,没有关系, 实现9好.
请分享下您的代码吧.

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
8 [报告]
发表于 2014-02-12 08:47 |只看该作者
本帖最后由 w_anthony 于 2014-02-12 08:49 编辑

这个我倒是知道,只是比较麻烦,代码量有点多
不过我不是用内置的Ole对象,而是用自定义的方式来实现的

论坛徽章:
0
7 [报告]
发表于 2014-02-12 08:42 |只看该作者
gaojl0728 发表于 2014-02-11 17:38
搞不定啊,帮不上什么忙了。


没事儿,交流一下!
谢谢您的思路!

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
6 [报告]
发表于 2014-02-11 17:38 |只看该作者
搞不定啊,帮不上什么忙了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP