问题是这样产生的.在OnEraseBkGnd中,如果你不调用原来缺省的OnEraseBkGnd只是重画背景则不会有闪烁.而在OnPaint里面,
由于它隐含的调用了OnEraseBkGnd,而你又没有处理OnEraseBkGnd 函数,这时就和窗口缺省的背景刷相关了.缺省的 OnEraseBkGnd操作使用窗口的缺省背景刷刷新背景(一般情况 下是白刷),而随后你又自己重画背景造成屏幕闪动. 另外一个问题是OnEraseBkGnd不是每次都会被调用的.如果你调用Invalidate的时候参数为TRUE,那么在OnPaint里面隐含 调用BeginPaint的时候就产生WM_ERASEBKGND消息,如果参数是FALSE,则不会重刷背景.
 
所以解决方法有三个半:
1.用OnEraseBkGnd实现,不要调用原来的OnEraseBkGnd函数.
2.用OnPaint实现,同时重载OnEraseBkGnd,其中直接返回.
3.用OnPaint实现,创建窗口时设置背景刷为空
4.用OnPaint实现,但是要求刷新时用Invalidate(FALSE)这样
的函数.(不过这种情况下,窗口覆盖等造成的刷新还是要闪一 下,所以不是彻底的解决方法) 都挺简单的.

在MFC中 任何一个window组件的绘图 都是放在这两个member function中在设定上 OnEraseBkgnd()是用来画底图的 而OnPaint()是用来画主要对象的
举例说明 一个按钮是灰色的 上面还有文字则OnEraseBkgnd()所做的事就是把按钮画成灰色而OnPaint()所做的事 就是画上文字

既然这两个member function都是用来画出组件的那为何还要分OnPaint() 与 OnEraseBkgnd() 呢? 其实OnPaint() 与 OnEraseBkgnd() 特性是有差的
1. OnEraseBkgnd()的要求是快速 在里面的绘图程序最好是不要太耗时间因为 每当window组件有任何小变动 都会马上呼叫OnEraseBkgnd()
2. OnPaint() 是只有在程序有空闲的时候才会被呼叫
3. OnEraseBkgnd() 是在 OnPaint() 之前呼叫的
所以 OnPaint()被呼叫一次之前 可能会呼叫OnEraseBkgnd()好几次

如果我们是一个在做图形化使用者接口的人,常会需要把一张美美的图片设为我们dialog的底图,把绘图的程序代码放在OnPaint() 之中 可能会常碰到一些问题
比方说拖曳一个窗口在我们做的dialog上面一直移动,则dialog会变成灰色 直到动作停止才恢复,这是因为每次需要重绘的时候 程序都会马上呼叫OnEraseBkgnd()
OnEraseBkgnd()就把dialog画成灰色,只有动作停止之后,程序才会呼叫OnPaint() 这时才会把我们要画的底图贴上去.

这个问题的解法 比较差点的方法是把OnEraseBkgnd() 改写成不做事的function,如下所示
BOOL CMyDlg::OnEraseBkgnd(CDC* pDC)
{
      return TRUE;
}
以上本来是会呼叫CDialog::OnEraseBkgnd() 但是如果我们不呼叫的话,程序便不会画上灰色的底色了

比较好的做法是直接将绘图的程序从OnPaint()移到OnEraseBkgnd()来做
如下所示

// m_bmpBKGND 为一CBitmap对象 且事先早已加载我们的底图
// 底图的大小与我们的窗口client大小一致

BOOL CMyDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rc;
GetUpdateRect(&rc);
CDC srcDC;
srcDC.CreateCompatibleDC(pDC);
srcDC.SelectObject(m_bmpBKGND);

pDC->BitBlt(rc.left,rc.top,rc.GetWidth(),
rc.GetHeight(),&srcDC,rc.left,rc.top,SRCCOPY);
return TRUE;
}

特别要注意的是 取得重画大小是使用GetUpdateRect() 而不是GetClientRect(),如果使用GetClientRect() 会把不该重画的地方重画.

关于OnEraseBkgnd和OnPaint的转载的更多相关文章

  1. OnPaint()函数的作用原理

    WM_PAINT是窗口每次重绘都会产生的一个消息. OnPaint是对这个消息的反应函数 mfc 的 CWnd::OnPaint 没做什么,只是丢给系统处理. 一 : 先执行OnEraseBkgnd, ...

  2. VC 绘图,使用双缓冲技术实现

    VC 绘图,使用双缓冲技术实现 - Cloud-Datacenter-Renewable Energy-Big Data-Model - 博客频道 - CSDN.NET VC 绘图,使用双缓冲技术实现 ...

  3. MFC绘制图片闪烁详解

    用MFC如何高效地绘图             显示图形如何避免闪烁,如何提高显示效率是问得比较多的问题.     而且多数人认为MFC的绘图函数效率很低,总是想寻求其它的解决方案.     MFC的 ...

  4. [转]Windows的窗口刷新机制

    1.Windows的窗口刷新管理 窗口句柄(HWND)都是由操作系统内核管理的,系统内部有一个z-order序列,记录着当前窗口从屏幕底部(假象的从屏幕到眼睛的方向),到屏幕最高层的一个窗口句柄的排序 ...

  5. VC++ SetLayeredWindowAttributes 部分窗口透明鼠标穿透

    在初始化中使用下面两行代码 ModifyStyleEx(0, WS_EX_LAYERED); ::SetLayeredWindowAttributes(m_hWnd, RGB(1, 255, 0), ...

  6. WM_PAINT和WM_ERASEBKGND消息

    1.OnPaint()函数是窗口重绘消息WM_PAINT的响应函数,当窗口重绘时会产生WM_ERASEBKGND消息和WM_PAINT消息,而且WM_ERASEBKGND会先于WM_PAINT产生,所 ...

  7. windows消息机制详解(转载)

    消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了.例如,单击鼠标.改变窗口尺寸.按下键盘上的一个键都会使Windows发送一个消息给应用程序.消息本身是作为一个记录传递给应用程序的 ...

  8. MFC中OnDraw()和OnPaint()的区别[转]

    问题 问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同? OnDraw()和OnPaint()好象兄弟俩,因为它们的工作 ...

  9. [MFC]MFC中OnDraw与OnPaint的区别

    问题 问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同? OnDraw()和OnPaint()好象兄弟俩,因为它们的工作 ...

随机推荐

  1. Poj.Grids 2951 浮点数求高精度幂

    2951:浮点数求高精度幂 总时间限制: 1000ms 内存限制: 65536kB 描述 有一个实数 R ( 0.0 < R < 99.999 ) ,要求写程序精确计算 R 的 n 次方. ...

  2. 利用反射实现类通用的DAO层

    public void add(Object object) throws SQLException { ResultSet rs=null; PreparedStatement ps=null; C ...

  3. C++学习心得

    从大一的学习中,我了解到C++是兼容C的面向过程和面向对象的程序设计语言.其中,面向对象程序设计方法是以对象为模板的结构化程序设计方法,是对结构化程序设计方法的继承和发展.刚开始的学习让我觉得特别吃力 ...

  4. 纯练手设置ip地址脚本

    #!/bin/bash IFO() { read -p "Configure $line Network card ( 'yes'or'no' )?" CDN </dev/t ...

  5. Windows Server 2008更改远程桌面端口号

    windows 2008远程桌面端口默认是用的是3389端口,但是由于安全考虑,经常我们安装好系统后一般都会考虑把原来的3389端口更改为另外的端口. 更改过程: 打开注册表: 运行regedit 找 ...

  6. SQL提示介绍-强制并行

    查询提示一直是个很有争议的东西,因为他影响了sql server 自己选择执行计划.很多人在问是否应该使用查询提示的时候一般会被告知慎用或不要使用...但是个人认为善用提示在不修改语句的条件下,是常用 ...

  7. 【腾讯Bugly干货分享】QQ电话适配iOS10 Callkit框架

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/58009392302e4725036142fc Dev Club 是一个交流移动 ...

  8. PyQt5应用与实践

    一个典型的GUI应用程序可以抽象为:主界面(菜单栏.工具栏.状态栏.内容区域),二级界面(模态.非模态),信息提示(Tooltip),程序图标等组成.本篇根据作者使用PyQt5编写的一个工具,介绍如何 ...

  9. java提高篇(十三)-----equals()方法总结

    equals() 超类Object中有这个equals()方法,该方法主要用于比较两个对象是否相等.该方法的源码如下: public boolean equals(Object obj) { retu ...

  10. 将整数转换成二进制的java小程序

    首先我们知道,将整数转换成二进制是将整数除二取余将最后除得的数和得到的余数从下向上写,组成得到的二进制数. java程序实现如下: public class ChangeToErjinzhi { pu ...