关于刷新机制的问题 OnEraseBkgnd(),OnPaint(),OnDraw() 这几个都是对控件来刷新的,能不能比较下,它们接受消息及调用的顺序是怎么样的?谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 OnDraw()和OnPaint()兄弟作者:雷神主页:http://www.ai361.com经常有朋友问雷神这样的问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同?雷神在这里一并解答一下吧。OnDraw()和OnPaint()好象兄弟俩,因为它们的工作类似。至于不见了的问题简单,因为当你的窗口改变后,会产生无效区域,这个无效的区域需要重画。一般Windows回发送两个消息WM_PAINT(通知客户区有变化)和WM_NCPAINT(通知非客户区有变化)。非客户区的重画系统自己搞定了,而客户区的重画需要我们自己来完成。这就需要OnDraw()或OnPaint()来重画窗口。OnDraw()和OnPaint()有什么区别呢?首先:我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,并且没有响应消息的功能。这就是为什么你用VC成的程序代码时,在视图类只有OnDraw没有OnPaint的原因。其次:我们在第《每天跟我学MFC》3的开始部分已经说到了。要想在屏幕上绘图或显示图形,首先需要建立设备环境DC。其实DC是一个数据结构,它包含输出设备(不单指你17寸的纯屏显示器,还包括打印机之类的输出设备)的绘图属性的描述。MFC提供了CPaintDC类和CWindwoDC类来实时的响应,而CPaintDC支持重画。当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。///CView默认的标准的重画函数void CView::OnPaint(){ CPaintDC dc(this); OnPreparDC(&dc); OnDraw(&dc); //调用了OnDraw}既然OnPaint最后也要调用OnDraw,因此我们一般会在OnDraw函数中进行绘制。下面是一个典型的程序///视图中的绘图代码首先检索指向文档的指针,然后通过DC进行绘图调用。void CMyView::OnDraw( CDC* pDC ){ CMyDoc* pDoc = GetDocument(); CString s = pDoc->GetData(); // Returns a CString CRect rect; GetClientRect( &rect ); pDC->SetTextAlign( TA_BASELINE | TA_CENTER ); pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );}最后:现在大家明白这哥俩之间的关系了吧。因此我们一般用OnPaint维护窗口的客户区(例如我们的窗口客户区加一个背景图片),用OnDraw维护视图的客户区(例如我们通过鼠标在视图中画图)。当然你也可以不按照上面规律来,只要达到目的并且没有问题,怎么干都成。补充:我们还可以利用Invalidate(),ValidateRgn(),ValidateRect()函数强制的重画窗口,具体的请参考MSDN吧。 OnEraseBkgnd(),一般是在OnPaint里调用的!在OnPaint里调用BeginPaint(或CPaintDC),BeginPaint调用WM_ERASEBKGND,其中参数PAINTSTRUCT结构的成员fErase 决定background是否要be erased http 函数 是打开网页的吗?httpsendrequest 和打开网络地址有关吗?谢9999辈子 VC实现多国语言 关于delete 一个指针出错的问题,提示堆栈出错,请高手帮助,感谢! 请教高手 简单socket问题, 回答最快的马上拿分 100分求教:一个vcADO编程的问题? 询问软件皮肤方面的问题 回来转悠一下,问问:VC过时没有?参予者有分。 在win2000下如何修改注册表 书错了吗???? date time picker控件可以把时间设置为少于1971年的年份么? 有关com编程的问题,高手请进!!!
作者:雷神
主页:http://www.ai361.com经常有朋友问雷神这样的问题:
我在视图画的图象或者文字,当窗口改变后为什么不见了?
OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同?雷神在这里一并解答一下吧。
OnDraw()和OnPaint()好象兄弟俩,因为它们的工作类似。至于不见了的问题简单,因为当你的窗口改变后,会产生无效区域,这个无效的区域需要重画。一般Windows回发送两个消息WM_PAINT(通知客户区有变化)和WM_NCPAINT(通知非客户区有变化)。非客户区的重画系统自己搞定了,而客户区的重画需要我们自己来完成。这就需要OnDraw()或OnPaint()来重画窗口。OnDraw()和OnPaint()有什么区别呢?
首先:
我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,并且没有响应消息的功能。这就是为什么你用VC成的程序代码时,在视图类只有OnDraw没有OnPaint的原因。其次:
我们在第《每天跟我学MFC》3的开始部分已经说到了。要想在屏幕上绘图或显示图形,首先需要建立设备环境DC。其实DC是一个数据结构,它包含输出设备(不单指你17寸的纯屏显示器,还包括打印机之类的输出设备)的绘图属性的描述。MFC提供了CPaintDC类和CWindwoDC类来实时的响应,而CPaintDC支持重画。当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。///CView默认的标准的重画函数
void CView::OnPaint()
{
CPaintDC dc(this);
OnPreparDC(&dc);
OnDraw(&dc); //调用了OnDraw
}既然OnPaint最后也要调用OnDraw,因此我们一般会在OnDraw函数中进行绘制。下面是一个典型的程序///视图中的绘图代码首先检索指向文档的指针,然后通过DC进行绘图调用。
void CMyView::OnDraw( CDC* pDC )
{
CMyDoc* pDoc = GetDocument();
CString s = pDoc->GetData(); // Returns a CString
CRect rect; GetClientRect( &rect );
pDC->SetTextAlign( TA_BASELINE | TA_CENTER );
pDC->TextOut( rect.right / 2, rect.bottom / 2,
s, s.GetLength() );
}最后:
现在大家明白这哥俩之间的关系了吧。因此我们一般用OnPaint维护窗口的客户区(例如我们的窗口客户区加一个背景图片),用OnDraw维护视图的客户区(例如我们通过鼠标在视图中画图)。当然你也可以不按照上面规律来,只要达到目的并且没有问题,怎么干都成。补充:
我们还可以利用Invalidate(),ValidateRgn(),ValidateRect()函数强制的重画窗口,具体的请参考MSDN吧。