原创 OnDraw()和OnPaint()

2009-2-19 17:37 4388 6 6 分类: 软件与OS


对于窗口的绘制在消息传递哪里介绍了一些

对于OnDraw()和OnPaint()之间 的关系这里再复习一下


当你的窗口改变后,会产生无效区域,这个无效的区域需要重画。一般Windows回发送两个消息WM_PAINT(通知
客户区有变化)和WM_NCPAINT(通知非客户区有变化)。非客户区的重画系统自己搞定了,而客户区的重画需要我们自己来完成。这就需要
OnDraw()或OnPaint()来重画窗口。


OnDraw()和OnPaint()的区别:
CView类派生自CWnd类,而OnPaint()是
CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,并且没有响应消息的功能。


当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint
处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint
处理成员函数。


///CView默认的标准的重画函数
void CView::OnPaint()
{
    CPaintDC dc(this);
    OnPreparDC(&dc);
    OnDraw(&dc); //调用了OnDraw
}

///////////////////////////////////////////////////

在MFC程序设计中,按照传统的设计,如果处理WM_PAINT消息,一般会派生一个OnPaint函数,映射到WM_PAINT消息上进行绘图处理。但
是很多程序中并没有出现OnPaint,一个OnDraw函数做了更多的绘图操作。而在消息映射的列表中,也没有见到WM_PAINT到OnDraw的映
射。
实际上,OnDraw不是OnPaint的映射,出现OnDraw,是为了实现各种不同的设备上的绘图一致性。
首先,读者需要明白的是,WM_PAINT消息是为了绘制屏幕而出现的,因此,在OnPaint中,我们只能存取屏幕DC,进行绘制,常见的代码是:
void MyWnd::OnPaint()
{
       CPaintDC dc(this);
     //draw code here
}

里的CPaintDC的构造函数会自动调用BeginPaint,获得一个屏幕DC,并附加在dc对象上。当dc对象析构时,系统自动调用
EndPaint并使invalidated
rectangle变成validated状态,从而结束绘制。(注意,重复创建CPaintDC实例会失败也因为如此)

如果我们在
OnPaint中绘制,那么在打印机上绘制我们就需要再写一个OnPrint函数,重新绘制。这样,程序设计者就需要维护两套代码。为了简化操作,MFC
框架把大部分绘制操作都放在OnDraw中,OnPaint和OnPrint只构造相应的DC,然后分别调用OnDraw.也就是说,OnDraw适用于
所有的设备,而OnPaint只适用于屏幕。

大家在设计过程中必须注意:OnDraw是被基类的OnPaint主动调用的,如果你继承了
OnPaint,你应该要么调用基类的OnPaint(此前不得创建CPaintDC实例,也不得调用BeginPaint),要么自己创建
CPaintDC实例,并调用OnDraw.




PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /3 下一条