控件的OnPaint不停刷新?加CPaintDC dc就没事?

wuzoujing 2009-12-04 07:30:21
自定义控件响应WM_PAINT消息,在OnPaint中,默认有CPaintDC dc(this);
void COpenGLControl::OnPaint()
{
CPaintDC dc(this); // device context for painting

}
如果注释掉CPaintDC dc(this);则程序不停地刷新(计数器不停地飞涨!!),可是如果保留CPaintDC dc(this);,如下:
void COpenGLControl::OnPaint()
{
CPaintDC dc(this); // device context for painting

//用于计数响应次数
static long aa=0;
CString str;
str.Format("%d",aa);
ATLTRACE(str);

//绘图函数
DrawGLScene();
}
则是正常响应。虽然问题解决了,但不知道具体原因???各位大大们帮忙~~~~帖子给分50!!
...全文
198 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
huangzhai127 2011-09-18
  • 打赏
  • 举报
回复
因为OnPaint是WM_PAINT消息函数,使用CpaintDC类后,才能从消息列队中删除掉该条消息,否则,Onpaint就会无限次响应WM_PAINT消息
wuzoujing 2009-12-04
  • 打赏
  • 举报
回复
真正原因得从CPaintDC说起。CPaintDC为窗口的OnPaint函数所使用的设备环境类。该类的构造
函数会自动调用BeginPaint函数,析构函数自动调用EndPaint函数。然后就是swq1982说的是BeginPaint作用。
erjun11_24 2009-12-04
  • 打赏
  • 举报
回复
不知道,进来见识见识
swq1982 2009-12-04
  • 打赏
  • 举报
回复
BeginPaint函数的作用就是将窗口需要重绘的区域设置为空(也就是Update Region置空)。在正常情况下,我们接收到了WM_PAINT消息后,窗口的Update Region都是非空的(如果为空就不需要发送WM_PAINT消息了)。而当你响应这个消息的时候又不调用BeginPaint来清空,窗口的Update Region就一直是非空的,系统就会一直发送WM_PAINT消息。这样就形成了一个处理WM_PAINT消息的死循环。这就是我出现错误的原因,低级错误。

  BeginPaint和WM_PAINT消息紧密相关。试一试在WM_PAINT处理函数中不写BeginPaint会怎样?程序会像进入了一个死循环一样达到惊人的CPU占用率,你会发现程序总在处理一个接 一个的WM_PAINT消息。这是因为在通常情况下,当应用收到WM_PAINT消息时,窗口的Update Region都是非空的(如果为空就不需要发送WM_PAINT消息了),BeginPaint的一个作用就是把该Update Region置为空,这样如果不调用BeginPaint,窗口的Update Region就一直不为空,如前所述,系统就会一直发送WM_PAINT消息。

  BeginPaint和WM_ERASEBKGND消息也有关系。当窗口的Update Region被标志为需要擦除背景时,BeginPaint会发送WM_ERASEBKGND消息来重画背景,同时在其返回信息里有一个标志表明窗口背景是否被重画过。当我们用InvalidateRect和InvalidateRgn来把指定区域加到Update Region中时,可以设置该区域是否需要被擦除背景,这样下一个BeginPaint就知道是否需要发送WM_ERASEBKGND消息了。

  当然关于 WM_PAINT消息还有很多的知识需要学习。另外要注意的一点是,BeginPaint只能在WM_PAINT处理函数中使用,并且在调用了BeginPaint函数后,不要忘记了调用EndPaint函数,他们可是一对的。
nintendo_dskay 2009-12-04
  • 打赏
  • 举报
回复
以前也碰到过一摸一样的问题,也是如果不加CPaintDC pDC(this)的话,就会不断闪烁,加了以后就没事。
帮楼主顶一下

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧