OnEraseBkgnd、OnPaint与画面重绘
来源:互联网 发布:淘宝卖鞋子的店铺 编辑:程序博客网 时间:2024/04/30 10:11
问题背景:
窗体在重绘时,由于过频的刷新会引起闪烁现象——窗体在刷新时,总要有一个擦除原来图象的过程OnEraseBkgnd,它利用背景色填充窗体绘图区,然后在调用新的绘图代码进行重绘,这样一擦一写造成了图象颜色的反差。当WM_PAINT的响应很频繁的时候,这种反差也就越发明显。绘制过程:
当窗口整体需要重绘时,系统依次发送WM_NCPAINT、WM_ERASEBKGND、WM_PAINT三个独立的消息,即先绘制框架部分,再绘制客户区背景,最后绘制客户区,根据需要也可能只产生其中某一个消息响应。任何一个window组件的绘图,都是放在OnPaint、OnEraseBkgnd中。在设定上 OnEraseBkgnd是用来画底图的而OnPaint是用来画主要对象的。举例说明:一个按钮是灰色的,上面还有文字,则OnEraseBkgnd所做的事就是把按钮画成灰色,而OnPaint()所做的事就是画上文字。
产生原因:
在OnEraseBkGnd中,如果不调用原来缺省的OnEraseBkGnd只是重画背景则不会有闪烁。而在OnPaint里面,由于它隐含的调用了OnEraseBkGnd,如果没有处理OnEraseBkGnd
解决思路:
1.用OnEraseBkGnd实现,不要调用基类的OnEraseBkGnd函数。2.用OnPaint实现,同时重载OnEraseBkGnd,其中直接返回。
3.用OnPaint实现,创建窗口时设置背景刷为空(不能将先前的图像擦除)。
4.用OnPaint实现,但是要求刷新时用Invalidate(FALSE)这样的函数(这种情况下,窗口覆盖等造成的刷新还是要闪一下,所以不是彻底的解决方法)。
思路解决归纳:
比较OnPaint与OnEraseBkgnd:1、
2、
3、
在OnPaint之前,可能调用OnEraseBkgnd好几次,所以比较好的方法是OnPaint的方法由OnEraseBkgnd实现。
WM_PAINT消息响应的频度太高,最小化最大化,移动窗体,覆盖等等都引起重绘,很是消耗性能。
故使用双缓存:可以把要显示的图形先在内存中绘制好,然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去。
综上,采用重载OnEraseBkgnd,通过双缓存来解决画面闪烁问题。
示例代码:
BOOL CSDRClientDlg::OnEraseBkgnd(CDC* pDC){
// TODO: Add your message handler code here and/or call default
CRect rcClient;
GetClientRect(&rcClient);
BITMAP bmpBKG;
m_cBKGndBmp.GetBitmap(&bmpBKG);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap *pOldBmp=memDC.SelectObject(&m_cBKGndBmp);
pDC->StretchBlt(0,0,rcClient.Width(),rcClient.Height(),&memDC,0,0,
bmpBKG.bmWidth,bmpBKG.bmHeight,SRCCOPY);
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
return TRUE;
//return CDialog::OnEraseBkgnd(pDC);
- OnEraseBkgnd、OnPaint与画面重绘
- OnEraseBkgnd、OnPaint与画面重绘
- OnEraseBkgnd、OnPaint与画面重绘
- OnEraseBkgnd、OnPaint与画面重绘
- OnEraseBkgnd、OnPaint与画面重绘(很好的说明其调用实现关系)
- OnPaint()与OnEraseBkgnd()
- OnPaint()与OnEraseBkgnd()
- OnEraseBkgnd与OnPaint
- OnEraseBkGnd与OnPaint
- OnEraseBkGnd与OnPaint
- OnPaint()与OnEraseBkgnd()的差异
- OnPaint()与OnEraseBkgnd()的差异
- OnEraseBkGnd与OnPaint的联系
- OnEraseBkGnd与OnPaint的联系 .
- OnPaint与OnEraseBkGnd的关系
- OnEraseBkGnd与OnPaint的联系
- OnEraseBkGnd与OnPaint的区别与联系
- OnEraseBkGnd与OnPaint的区别与联系
- 老子的软件之道 - 道篇 9 企业之道
- in和exists 区别
- 位运算简介及实用技巧(四):实战篇
- Java反编译-在MyEclipse安装Jad反编译插件
- 相关子查询和嵌套子查询 [SQL Server]
- OnEraseBkgnd、OnPaint与画面重绘
- Unity3D游戏引擎初探
- SELECT语句的执行顺序
- RESIN下配置EJB有四个步骤
- truncate,delete,drop
- NSAttributedString
- NDK Build 参数
- javascript 遍历一个对象object 有时会用到(转自:http://blog.csdn.net/peng_wu01/article/details/5569247)
- UPDATE、DELETE 语句中的子查询