2010.7.27 OnDraw与OnPaint有什么区别

引用:http://wenku.baidu.com/view/bc9b1c661ed9ad51f01df2ab.html

 

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()等。


对于OnDraw()
This method is called by the framework to render an image of the document. The framework calls this method to perform screen display, printing, and print preview, and it passes a different device context in each case. There is no default implementation.

 

转载于:https://www.cnblogs.com/peijihui/archive/2010/07/27/1786241.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304089.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

D轮融资1亿美金,6亿美金估值,3位计算机学霸如何带领海归团队创造业内神话?!

顺为资本在创始合伙人雷军及许达来的带领下成功领投了51Talk、丁香园、爱奇艺、一起作业等超级公司有近20家公司估值超过10亿美元如今顺为资本为何愿意投资这家公司?酷家乐6年破6亿美金的公司估值17年全年营收超3亿有着设计师300万这家以家居云设计为核心的创业公司…

linux下mysql案例_Linux下安装MySQL多实例

环境说明:Centos 6.6 64位mysql 使用最新版本5.7.16版本这里安装两个MySQL实例,分别使用3306/3307端口号目录结构:/data/mysql/mysql3306/data/mysql/mysql3306/data/data/mysql/mysql3307/log/data/mysql/mysql3306/tmp执行命令:…

Navicat

作为Oracle, MySQL, Sqlite, PostgreSQL的统一客户端,Navicat无疑是最方便简洁的,而且界面非常友好。导入导出支持的格式也很全。 在连Oracle的时候,会报错说字符集不支持。只要手工指定OCI就好,方法如下: 在OCI libra…

分布式链路追踪框架的基本实现原理

目录分布式追踪分布式系统分布式追踪分布式追踪有什么用呢什么是分布式追踪Dapper分布式追踪系统的实现跟踪树和 spanJaeger 和 OpenTracingOpenTracing 数据模型Span 格式TraceOpenTracingJaeger 结构SpanOpenTracing API分布式追踪什么是分布式追踪分布式系统当我们使用 Goog…

mysql外键约束创建及删除_MySQL中的外键的创建,约束和删除

一、外键的创建语法一:后续添加方法alter table 表名 add constraint 约束名 foreign key(当前表中约束的字段) references 主表表名(要约束的字段名);alter table student add constraint fk_class_student foreign key(cls_id) class(cls_id) on update cascade o…

不爱读书怎么办?用这个新奇的方法,熟知137亿年来的地球通史

今天,小木为模友们挑选的小荐货:《地球通史墙书》第一次接触《地球通史》墙书的时候,虽然“地球通史”的概念非常吸引我,但“墙书”的叫法怎么听都像是一个噱头,所以小木一直有些莫名的排斥,直到在小天把试…

测试驱动开发简介

本文节选自《测试驱动的面向对象软件开发》 第1章第4节“测试驱动开发简介” TDD核心的循环是:写一个测试;写一些代码让测试通过;重构代码,使被测试特征的实现尽可能简单。重复这个过程,如图1-1所示。 图1-1基本TDD循环…

在 .NET 中使用 Flurl 高效处理Http请求

简介官方介绍,Flurl是一个现代的,流利的,支持异步的,可测试的,可移植的,URL增强和Http客户端组件。Url构建现在有一个登录的接口,地址如下:https://www.some-api.com/login?nameLee…

java jdbc 删除_java使用jdbc实现各种类型添加删除修改数据

项目描述上次为大家分享了使用jdbc实现各种类型查询数据,这次为大家分享使用jdbc实现各种类型添加、删除、修改数据运行环境jdk8tomcat7mysql项目技术(必填)jdbcdao层数据库文件DROP TABLE IF EXISTS class;CREATE TABLE class (id int(11) NOT NULL auto_increment…

图像还可以这样玩!如何用波的算法处理图像

我对图像处理一直很感兴趣,曾经写过好几篇博客。前几天读到一篇文章,它提到图像其实是一种波,可以用波的算法处理图像。我顿时有一种醍醐灌顶的感觉,从没想到这两个领域是相关的,图像还可以这样玩!下面我就…

[存档]CxServer的项目周期管理

2019独角兽企业重金招聘Python工程师标准>>> 主题:大学生创新性实验计划 项目周期管理 作者:宋志民备注:本文为《 基于CxServer的大学生科学研究项目管理实践探索》的一部分 内容: 一般情况下大学生科研计划的种类较多…

C# 在PC上的通过蓝牙(bluetooth)发送数据到手机

概述在PC端用.NET开发一个蓝牙下载的程序。实现在PC上查找周围的蓝牙设备(主要是手机),并将PC上的文件通过蓝牙传输到手机上。目前我采用的是OpenNETCF.Net.Bluetooth,能够正常发现周围的蓝牙设备,手机也能够正常进行蓝…

新浪股票接口 java_新浪股票接口Android SDK(非官方)

新浪股票接口AndroidSDK昨天想到一个点子,需要访问股票行情。于是在网上搜了一下免费的股市行情的接口。发现新浪股票的数据接口比较稳定,于是就用它了。网上对于新浪股票的数据接口介绍比较详细,并且实现也很简单,所以花了一下午…

VC++的dll中接收消息

LRESULT CALLBACK MessageWinProc(HWND hwnd, // handle to windowUINT uMsg, // message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter)//用于处理消息窗口接收到的消息{switch(uMsg){case WM_CLOSE:DestroyW…

在职场中,长得漂亮真的有用吗?

非常有用。下面五张图,每张图介绍一个研究,都可以从一个侧面回答问题。01 企业对求职者的颜值有多看重?这张图来自两位学者对国内某网站超过100万份招聘广告的分析结果。总的来看,有7.7%的企业会对应聘者的外貌提出要求&#xff0…

TIOBE 3月榜单:新功能将加入,C语言仍高居榜首

喜欢就关注我们吧!TIOBE 公布了 2021 年 3 月的编程语言排行榜。本月 TIOBE 指数没有什么有趣的变化。因此,TIOBE CEO Paul Jansen 表示,其打算透露一些近期将加入至榜单中的新功能。第一个问题涉及到一个 bug 修复。由于使用了复杂的算法&am…

java jdk win10安装_Java 安装 JDK WIN10

JDK的全称是Java SE Development Kit它的官方网站只要用Goole搜索下即可找到,官方提供JDK8、11、12的下载入口。我们点击Java SE Development Kit 8进入下载。我们下载的版本是jdk-8u91-windows-x64.exe安装过程按导向默认安装,中途什么选项都不改。安装…

twitter达人不能不知的缩写

今天上午有人在新闻编辑室问“嘿,Twitter上的MT是什么意思?”,让我们觉得编制一个Twitter缩写的列表可能会有帮助。 这就是为什么我们要做这些的原因。想要全面地完成其实不容易,所以请在评论中增加这个列表中缺失的缩写吧。技术类…

50张神图……好不容易才找到完整版!

描述:1.耶鲁大学耗时5年的研究成果。 如果你看见这个舞女是顺时针转,说明你用的是右脑 如果是逆时针转,说明你用的左脑。 据说,14%的美国人可以两个方向都能看见 可以和别人一起看,测试下,一般不同人同时看…

BeetleX.Http.Clients V1.5发布

组件开始设计是针对以接口的方式来定义HTTP/HTTPS访问,虽然基于接口来操作有很大的便利性,但定义起来就比较麻烦了。所以在1.5版本中实现了一个HttpClient类来简化调用。HttpClient 该类支持HTTP的GET,POST,DELETE和PUT操作,通过这几个…