OnPaint和OnDraw的区别

摘要:
OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同?而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。这就是为什么你用VC成的程序代码时,在视图类只有OnDraw没有OnPaint的原因。MFC提供了CPaintDC类和CWindwoDC类来实时的响应,而CPaintDC支持重画。该视图的OnPaint处理函数通过创建CPaintDC类的DC对象来响应该消息并调用视图的OnDraw成员函数。因此我们一般用OnPaint维护窗口的客户区,用OnDraw维护视图的客户区。

问题:

我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同?

答:

OnDraw()和OnPaint()好象兄弟俩,因为它们的工作类似。至于不见了的问题简单,因为当你的窗口改变后,会产生无效区域,这个无效的区域需要重画。一般Windows会发送两个消息WM_PAINT(通知客户区 有变化)和WM_NCPAINT(通知非客户区有变化)。非客户区的重画系统自己搞定了,而客户区的重画需要我们自己来完成。这就需要OnDraw()或 OnPaint()来重画窗口。

OnDraw()和OnPaint()有什么区别呢?

首先:我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,并且没有响应消息的功能。这就是为什么你用VC成的程序代码时,在视图类只有 OnDraw没有OnPaint的原因。

其次,要想在屏幕上绘图或显示图形,首先需要建立设备环境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维护视图的客户区(例如我们通过鼠标在视图中画图)。当然你也可以不按照上面规律来,只要达到目的并且没有问题,怎么干都成。

免责声明:文章转载自《OnPaint和OnDraw的区别》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Django(55)GenericAPIView源码分析bower简明入门教程下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SVG研究之路(一)

https://css-tricks.com/mega-list-svg-information/ rect 矩形 <svg height='200'> <g transform="translate(10 50) rotate(-30)"> <!-- 移动 (10,50) 旋转 -30 -->...

Winform 自定义文本框

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading....

ggplot2 theme相关设置—矩形设置(rect)

在主题设置中,rect设置主要用于设置图例和面板 element_rect(fill = NULL, colour = NULL, size = NULL, linetype = NULL, color = NULL) 参数也相对简单,基本上是常用的参数,从设置来看,灵活性还是很高的。 下面看些例子: library(ggplot2) p<-ggpl...

[ PyQt入门教程 ] Qt Designer工具的使用

Qt Designer是PyQt程序UI界面的实现工具,使用Qt Designer可以拖拽、点击完成GUI界面设计,并且设计完成的.ui程序可以转换成.py文件供python程序调用。本文主要通过用户登录需求描述Qt Designer工具开发界面的使用方法。 本文主要内容1、Qt Designer程序主界面窗口介绍。 2、Qt Designer程序实现界面...

GSAP JS基础教程--使用缓动函数

今天来了解一下缓动easeing函数。 开始,如果你还没有GSAP的类包,可以到GreenSock的官网去下载最新版本的类包,或者直接点击这里​来下载 学习之前,先来准备一下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/...

Windows RDP的RCE漏洞分析和复现(CVE-2019-0708)

0x00 漏洞描述Windows系列服务器于2019年5月15号,被爆出高危漏洞,该漏洞影响范围较广如:windows2003、windows2008、windows2008 R2、windows xp系统都会遭到攻击,该服务器漏洞利用方式是通过远程桌面端口3389,RDP协议进行攻击的。这个漏洞是今年来说危害严重性最大的漏洞,跟之前的勒索,永恒之蓝病毒差...