OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。

OnPaint()是CWnd的类成员,负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,没有响应消息的功能.当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows发送WM_PAINT消息。该视图的OnPaint 处理函数通过创建CPaintDC类的DC对象来响应该消息并调用视图的OnDraw成员函数.OnPaint最后也要调用OnDraw,因此一般在OnDraw函数中进行绘制。

The WM_PAINT message is sent when the UpdateWindow or RedrawWindow member function is called.

在OnPaint中,将调用BeginPaint,用来获得客户区的显示设备环境,并以此调用GDI函数执行绘图操作。在绘图操作完成后,将调用EndPaint以释放显示设备环境。而OnDraw在BeginPaint与EndPaint间被调用。

1) 在mfc结构里OnPaint是CWnd的成员函数. OnDraw是CView的成员函数.
2) OnPaint()调用OnDraw(),OnPrint也会调用OnDraw(),所以OnDraw()是显示和打印的共同操作。

OnPaint是WM_PAINT消息引发的重绘消息处理函数,在OnPaint中会调用OnDraw来进行绘图。OnPaint中首先构造一个CPaintDC类得实例,然后一这个实例为参数来调用虚函数OnPrepareDC来进行一些绘制前的一些处理,比设置映射模式,最后调用OnDraw。而OnDraw和OnPrepareDC不是消息处理函数。所以在不是因为重绘消息所引发的OnPaint导致OnDraw被调用时,比如在OnLButtonDown等消息处理函数中绘图时,要先自己调用OnPrepareDC。
至于CPaintDC和CClientDC根本是两回事情 CPaintDC是一个设备环境类,在OnPaint中作为参数传递给OnPrepareDC来作设备环境的设置。真正和CClientDC具有可比性的是CWindowDC,他们一个是描述客户区域,一个是描述整个屏幕。
如果是对CVIEW或从CVIEW类派生的窗口绘图时应该用OnDraw。

OnDraw()和OnPaint()有什么区别呢?
首先:我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,并且没有响应消息的功能。这就是为什么你用VC成的程序代码时,在视图类只有OnDraw没有OnPaint的原因。而在基于对话框的程序中,只有OnPaint。
其次:我们在第《每天跟我学MFC》3的开始部分已经说到了。要想在屏幕上绘图或显示图形,首先需要建立设备环境DC。其实DC是一个数据结构,它包含输出设备(不单指你17寸的纯屏显示器,还包括打印机之类的输出设备)的绘图属性的描述。MFC提供了CPaintDC类和CWindwoDC类来实时的响应,而CPaintDC支持重画。当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows 将 WM_PAINT 消息发送给它。该视图的OnPaint 处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。
///CView默认的标准的重画函数
void CView::OnPaint() //见VIEWCORE.CPP
{

CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc); //调用了OnDraw
}
///CView默认的标准的OnPrint函数
void CView::OnPrint(CDC* pDC, CPrintInfo*)
{
ASSERT_VALID(pDC);
OnDraw(pDC); // Call Draw
}

既然OnPaint最后也要调用OnDraw,因此我们一般会在OnDraw函数中进行绘制。下面是一个典型的程序。
///视图中的绘图代码首先检索指向文档的指针,然后通过DC进行绘图调用。
void CMyView::OnDraw( CDC* pDC )
{

CMyDoc* pDoc = GetDocument();
CString s = pDoc->GetData();
GetClientRect( &rect ); // Returns a CString CRect rect;
pDC->SetTextAlign( TA_BASELINE | TA_CENTER );
pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );
}
最后:现在大家明白这哥俩之间的关系了吧。因此我们一般用OnPaint维护窗口的客户区(例如我们的窗口客户区加一个背景图片),用OnDraw维护视图的客户区(例如我们通过鼠标在视图中画图)。当然你也可以不按照上面规律来,只要达到目的并且没有问题,怎么干都成。补充:我们还可以利用Invalidate(),ValidateRgn(),ValidateRect()函数强制的重画窗口,具体的请参考MSDN吧。

OnDraw中可以绘制用户区域。OnPaint中只是当窗口无效时重绘不会保留CClientDC绘制的内容。

这两个函数有区别也有联系:

1、区别:OnDraw是一个纯虚函数,定义为virtual void OnDraw( CDC* pDC ) = 0; 而OnPaint是一个消息响应函数,它响应了WM_PANIT消息,也是是窗口重绘消息。

2、联系:我们一般在视类中作图的时候,往往不直接响应WM_PANIT消息,而是重载OnDraw纯虚函数,这是因为在CVIEW类中的WM_PANIT消息响应函数中调用了OnDraw函数,如果在CMYVIEW类中响应了WM_PAINT消息,不显式地调用OnDraw函数的话,是不会在窗口重绘的时候调用OnDraw函数的。

应用程序中几乎所有的绘图都在视图的 OnDraw 成员函数中发生,必须在视图类中重写该成员函数。(鼠标绘图是个特例,这在通过视图解释用户输入中讨论。)

OnDraw 重写:
通过调用您提供的文档成员函数获取数据。
通过调用框架传递给 OnDraw 的设备上下文对象的成员函数来显示数据。
当文档的数据以某种方式更改后,必须重绘视图以反映该更改。默认的 OnUpdate 实现使视图的整个工作区无效。当视图变得无效时,Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的设备上下文对象来响应该消息并调用视图的 OnDraw 成员函数。

当没有添加WM_PAINT消息处理时,窗口重绘时,由OnDraw来进行消息响应...当添加WM_PAINT消息处理时,窗口重绘时,WM_PAINT消息被投递,由OnPaint来进行消息响应.这时就不能隐式调用OnDraw了.必须显式调用( CDC *pDC=GetDC(); OnDraw(pDC); )..
隐式调用:当由OnPaint来进行消息响应时,系统自动调用CView::OnDraw(&pDC).

想象一下,窗口显示的内容和打印的内容是差不多的,所以,一般情况下,统一由OnDraw来画。窗口前景需要刷新时,系统会会调用到OnPaint,而OnPaint一般情况下是对DC作一些初始化操作后,调用OnDraw()。

OnEraseBkGnd(),是窗口背景需要刷新时由系统调用的。明显的一个例子是设置窗口的背景颜色(你可以把这放在OnPaint中去做,但是会使产生闪烁的现象)。
至于怎么界定背景和前景,那要具体问题具体分析了,一般情况下,你还是很容易区别的吧。

的确,OnPaint()用来响应WM_PAINT消息,视类的OnPaint()内部根据是打印还是屏幕绘制分别以不同的参数调用OnDraw()虚函数。所以在OnDraw()里你可以区别对待打印和屏幕绘制。
其实,MFC在进行打印前后还做了很多工作,调用了很多虚函数,比如OnPreparePrint()等。
转自:http://hi.baidu.com/proworkspace/blog/item/fd97a650322a8a541038c27d.html
文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppjs/20100208/195311.html)

转载于:https://www.cnblogs.com/vc_zgj/archive/2010/03/15/1686468.html

MFC中OnDraw与OnPaint的区别相关推荐

  1. MFC中MessageBox和AfxMessageBox函数区别和用法

    MessageBox函数定义: //__WINUSER_H__中定义:(Win32 API)#define MessageBox MessageBoxAint WINAPI MessageBoxA(H ...

  2. C#中 paint()与Onpaint()的区别

    paint是事件onpaint方法onpaint方法是调用paint事件的,用哪一个,效果是一样,就看那一个方便了内部是这样实现的: 复制代码 代码如下: protected virtual OnPa ...

  3. MFC中的Invalidate、OnDraw、OnPaint函数的作用及绘图概念

    1.绘图概念 GDI绘图分为背景和前景两个画布的绘制,Invalidate()函数强制重绘制, Invalidate()     如果参数为true则在OnPaint函数对背景先进行绘制,再对前景进行 ...

  4. 【VC++ MFC】vc 画笔和画刷|OnDraw()和OnPaint()

    目录 [VC++ MFC]vc 画笔和画刷 [VC++ MFC]OnDraw()和OnPaint() [VC++ MFC]vc 画笔和画刷 6,利用画笔改变线条颜色和类型: CPen pen(PS_D ...

  5. OnDraw与OnPaint有什么区别

    学习中遇到一个问题,OnDraw与OnPaint有什么区别?上网搜索了一下,又查了一下MSDN和MFC的一些源文件,现整理如下. OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中 ...

  6. 2010.7.27 OnDraw与OnPaint有什么区别

    引用:http://wenku.baidu.com/view/bc9b1c661ed9ad51f01df2ab.html OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用On ...

  7. OnDraw和OnPaint函数的区别

    CWnd::OnPaint() 是CWnd类的成员函数,是WM_PAINT 消息的响应函数.当你调用CWnd::UpdateWindow(),CWnd::RedrawWindow()时, 或者窗口被其 ...

  8. VC++中多线程学习(MFC多线程)一(线程的创建、线程函数如何调用类成员呢?如何调用主对话框的成员?、MFC中的工作线程和界面线程的区别)

    这里废话不多讲了,因为项目原因,需要开启线程进行处理,在不了解线程的情况下,直接百度一下,然后就使用了,结果可想而知,出现了异常,所以花了一天时间系统学习一下多线程,这里主要是针对win32编程方面的 ...

  9. MFC中模态对话框和非模态对话框的区别

    MFC中对话框有两种形式,一个是模态对话框(model dialog box),一个是非模态对话框(modeless dialog box).二者的区别在于当对话框打开时,是否允许用户进行其他对象的操 ...

最新文章

  1. 【EI/Scopus检索】第六届电子技术与信息科学国际学术会议诚邀您投稿参会!
  2. css表格文字超数量就竖排_求助!!一个非常棘手的问题。就是文字竖排显示的问题...
  3. OHCI,UHCI,EOHCI,XHCI
  4. docker run hello-world 遇到错误消息 - error during connect
  5. python怎么设置颜色深浅变化_Python赋值、深浅copy
  6. Win7中的文件关联注册表
  7. 前端面试题(附上自己的回答)
  8. 关于阿里云服务器本地访问不了的问题
  9. 002Linux应用领域
  10. 安装nokogiri前提
  11. 一个简单的现代化公司域名使用规律预测及生成工具
  12. android studio 如何导入 RecyclerView
  13. poj 2387 Til the Cows Come Home spfa基础题,入门,我的第一个
  14. 怎样从本地删除git远程仓库里面的文件
  15. 安装Windows10操作系统
  16. 测试网卡芯片型号的软件,查看电脑无线网卡型号_查看无线网卡芯片型号
  17. input标签用法与功能全面解析
  18. [java 手把手教程][第二季]java 后端博客系统文章系统——No7
  19. 原形网络(Prototypical Networks)基于PyTorch的实现
  20. 爬虫问题,内容应该如何解码,base64解码技巧,从哪里开始分析

热门文章

  1. 在NAnt中加入Vssget 任务
  2. 计算机数据库基础知识笔记,计算机基础及技巧(我的电脑笔记,适合新手!包含使用电脑最基本的知识及DOS、网络及数据库等。)...
  3. SpringSecurity权限控制之异常处理方式三
  4. SpringBoot配置文件-yaml的用法
  5. 构造器Constructor是否可被override
  6. 函数式接口作为方法的返回值
  7. 数据库-优化-子查询优化
  8. 伦茨8400变频器面板按键说明_变频器调试笔记
  9. 200903阶段一C++
  10. 电机串电阻会有什么影响?