好久没更新博客了,不是偷懒,而是考试前期太忙了,什么作业都要开始交,上周末就完成了三门课的实验报告,还有一部分课要提前考试。比方说最无聊的文献检索。没办法进行新的学习。等考试结束后,大概就要全面攻RHCE了。

今天验收Windows大作业,这个程序让我花费了很多力气,但是验收时并不怎么顺利。虽然结构和类封装让老师对我的C++水平印象深刻,但是在一段动画上却出了问题,动画不够流畅。

这段动画是一个辅助型的效果,一个Google的Logo的移动动画,要有透明效果。这段动画我完全没有采用过去常用的动画在时间类回调函数里做法,而是把动画做在WM_PAINT里,时间类回调函数仅仅只是更新Logo的位置,并请求刷新界面。问题就出在这里,刷新信息是放在消息队列里的,程序必须接收到重绘消息才会绘图,如果重绘消息过多就不会多次重绘,而是只重绘一次就草草结束(有点掏浆糊)。显然13帧的重绘消息程序是不可能一一处理(虽然我的电脑性能较好,程序处理了大部分信息,如果没有经验,是断然看不出他的不流畅),因此跳帧就出现了。解决方法还是按照老路子走,直接在时间类回调函数内取得HDC,让他动,流畅性将大大提高。

另外,之所以有时界面会闪烁,根本原因是重绘前的一瞬间,界面这块区域被涂白了(通常是因为发送了EraseBackground消息或是BitBlt最后一个参数是WHITENESS),涂白后又立刻在上面绘图,Windows的图形速度并不是很快,这一瞬间还是能被人眼捕捉到,这样就看上去在闪烁。对此的解决方案是,如果是因为EraseBackground的话,请尽可能限制Invalidate系列函数的使用,即使要用,也要尽可能把他的最后一个参数设置为FALSE,如果图像较复杂就干脆用兼容DC做缓冲,使用兼容DC的话是永远没必要EraseBackground的。如果是因为BitBlt的话,那么就尽可能缩小WHITENESS的区域,不让其实就不需要WHITENESS的区域变成WHITENESS,这样闪烁基本上就可以抑制住。再次强调,闪烁不是因为过快频率的重绘,也不是因为过大范围的重绘,而是过多次的瞬间残留影像,一定要对症下药。

虽然验收不顺利,成绩仅仅是A-,但是能获取这么多经验,还是好的。本周五晚上还要在忙活一晚,把程序的这些问题全部去除,争取第二次验收得A。

对获取设备描述表的简单总结

2010年10月09日 18:13

昨天晚上一直在纠结于绘图的问题。相同的创建删除DC的代码,放在WM_PAINT里是对的,放进WM_CREATE和WM_DESTROY就全错了,不知道为什么,后来才想起来,不同的事件必须用不同的创建DC的函数,不能混用。

WM_PAINT里要用BeginPaint和EndPaint函数来取得DC,进行重绘。

WM_CREATE里必须用GetDC来取得DC,ReleaseDC既可以在WM_CREATE,也可以在WM_DESTROY里,实现DC在全局有效。

GetWindowDC获取整个窗口的DC,连同客户区和非客户区,WM_NCPAINT(NC是非客户区,不是脑残)事件负责对非客户区的重绘。ReleaseDC负责删除它。

CreateDC获取整个屏幕的DC,似乎不仅限于屏幕使用,具体怎么用,我也不知道。由DeleteDC负责删除。

至于CreateCompatibleDC想必就不用说了。这函数名字起的不好,叫缓存DC还差不多。

就是这样~~最后热烈庆贺中国再获诺贝尔和平奖。

twitter logo GDI绘制

2010年9月27日 07:09

这次的作业,用GDI绘制任意卡通图,我不会画什么卡通图,于是就画了个twitter的logo。

按1(MM_TEXT),7(MM_ISOTROPIC),8(MM_ANISOTROPIC)会有不同的GDI映射。缩放窗口可以看出他们的区别。

继续阅读