【MFC】MFC中窗口重绘

MFC中窗口重绘

摘自:http://blog.csdn.net/shuilan0066/article/details/5859057

在刷新窗口时经常要调用重绘函数

MFC提供了三个函数用于窗口重绘

InvalidateRect(&Rect)

Invalidate()

UpdateWindow()

当需要更新或者重绘窗口时,一般系统会发出两个消息WM_PAINT(通知客户区有变化)和

WM_NCPAINT(通知非客户区有变化)
WM_NVPAINT系统会自己搞定
WM_PAINT消息对应的函数是OnPaint(),它是系统默认的接受WM_PAINT消息的函数,但我们一般在程序中做重绘时都在OnDraw函数中进行的,因为在ONPAIN函数中调用了ONDRAW函数。

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

上面讲到
        InvalidateRect(&Rect)、Invalidate()两个函数形式和功能差不多

但Invalidate是使得整个窗口无效,形成无效矩形,而InvalidateRect(&Rect)是
使得指定的区域无效

Invalidate()申明无效,等待WM_PAINT消息以便重绘,队列中无其他消息时系统会自动发送

UpdateWindow()会立即发送WM_PAINT,不过在它发送前,先调用GetUpdateRect(hWnd,NULL,TRUE)看有无可 绘制区域,如果没有则不发送消息

RedrawWindow()RedrawWindow()则是具有Invalidate()和UpdateWindow()的双特性。声明窗口的状态为无效,并立即更新窗口,立即调用WM_PAINT消息处理。

系统为什么不在调用Invalidate时发送WM_PAINT消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?这是因为系统把在窗口中的绘制操作当作一种低优先级的操作,于是尽 可能地推后做。不过这样也有利于提高绘制的效率:两个WM_PAINT消息之间通过InvalidateRect和InvaliateRgn使之失效的区域就会被累加起来,然后在一个WM_PAINT消息中一次得到 更新,不仅能避免多次重复地更新同一区域,也优化了应用的更新操作。像这种通过InvalidateRect和InvalidateRgn来使窗口区域无效,依赖于系统在合适的时机发送WM_PAINT消息的机 制实际上是一种异步工作方式,也就是说,在无效化窗口区域和发送WM_PAINT消息之间是有延迟的;有时候这种延迟并不是我们希望的,这时我们当然可以在无效化窗口区域后利用SendMessage 发送一条WM_PAINT消息来强制立即重画,但不如使用Windows GDI为我们提供的更方便和强大的函数:UpdateWindow和RedrawWindow。UpdateWindow会检查窗口的Update Region,当其不为空时才发送WM_PAINT消息;RedrawWindow则给我们更多的控制:是否重画非客户区和背景,是否总是发送WM_PAINT消息而不管Update Region是否为空等。

BeginPaint和WM_PAINT消息紧密相关。试一试在WM_PAINT处理函数中不写BeginPaint会怎样?程序会像进入了一个死循环一样达到惊人的CPU占用率,你会发现程序总在处理一个接 一个的WM_PAINT消息。这是因为在通常情况下,当应用收到WM_PAINT消息时,窗口的Update Region都是非空的(如果为空就不需要发送WM_PAINT消息了),BeginPaint的一个作用就是把该UpdateRegion置为空,这样如果不调用BeginPaint,窗口的Update Region就一直不为空,如前所述,系统就会一直发送WM_PAINT消息。

BeginPaint和WM_ERASEBKGND消息也有关系。当窗口的Update Region被标志为需要擦除背景时,BeginPaint会发送WM_ERASEBKGND消息来重画背景,同时在其返回信息里有一个标志表明窗口背景是否被重画过。当我们用InvalidateRect和InvalidateRgn来把指定区域加到Update Region中时,可以设置该区域是否需要被擦除背景,这样下一个BeginPaint就知道是否需要WM_ERASEBKGND消息了。

另外要注意的一点是,BeginPaint只能在WM_PAINT处理函数中使用。

时间: 2024-11-07 11:54:59

【MFC】MFC中窗口重绘的相关文章

MFC中窗口重绘

搬家于CSDN 2015-05-14 MFC提供了三个函数用于窗口重绘 InvalidateRect(&Rect) Invalidate() UpdateWindow() 当需要更新或者重绘窗口时,一般系统会发出两个消息WM_PAINT(通知客户区有变化)和 WM_NCPAINT    (通知非客户区有变化) WM_NVPAINT    系统会自己搞定 WM_PAINT         消息系统默认对应的函数是OnPaint(),但‍一般在重绘时都在OnDraw,因为在ONPAIN中调用了OND

MFC 窗口重绘问题

在客户区画直线等图形时, 发现当其最小化或者其他窗口遮挡时,出现窗口重绘,而将原来绘制的图形删除,上网上搜索知道,绘制图形的代码必须放置在Ondraw函数中,才能避免重绘时图形消失(因为一直在响应WM_PAINT消息,不断的重绘),但是这样做却只能保存最近的一次绘图,只适用于单幅固定的图形,对于其中有多幅图形就不能这么做了,解决的思路是:考虑到MFC时 文档/视图 类,视图CView负责数据的显示和修改,文档CDocument类负责数据的存储和加载,从而把数据管理和显示方法分离开来.我们在CDo

WM_PAINT消息在窗口重绘的时候产生,那什么时候窗口会重绘(异步工作方式,效率更高,灵活性更强)

Q:wm_paint消息在窗口重绘的时候产生,那什么时候窗口会重绘?? A: 严格地说,只有当收到WM_PAINT消息后窗口会重绘 但是引起这个消息的事件有很多, 比如: 首次创建 移动 改变大小 showwindow/ activate window/ invalidate window .... 系统为什么不在调用Invalidate时发送WM_PAINT消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?这是因为系统把在窗口中的绘制操作当作一种低优先级的操作,于是尽可能地

MFC窗口重绘

Invalidate()与 UpdateAllViews()有什么分别 Invalidate()是让程序重画窗口. UpdateAllViews()是在DOC/VIEW结构中, 当一个视图的数据改变后, 通知所有视图作相应的改变, 和重画毫无关系. Invalidate()是使窗口无效,使系统向其发WM_PAINT消息,使的程序的OnPaint被调用重画客户区. 而UpdateAllViews()是文档与视之间的联系,调用从它会使程序与此文档相关的所有视的UpdateView被调用至于是否重画以

窗口重绘

Windows程序运行时,如果程序窗口大小发生变化,窗口会发生重绘,窗口中已输入的文字或图像就会被擦除.如果希望输入的内容始终保留在窗口上,就要在响应WM_PAINT消息的函数中将内容再次输出.在MFCAppWizard的视图窗口中提供了类似于WM_PAINT消息响应函数的OnDraw函数,当窗口发生重绘时,应用程序框架代码就会调用该函数. OnDraw函数: void CTextView::OnDraw(CDC* pDC) { CTextDoc* pDoc = GetDocument(); A

IOS中对图片进行重绘处理的方法总结

一.CGImageRef是什么 CGImageRef是定义在QuartzCore框架中的一个结构体指针,用C语言编写.在CGImage.h文件中,我们可以看到下面的定义: ? 1 typedef struct CGImage *CGImageRef; CGImageRef 和 struct CGImage * 是完全等价的.这个结构用来创建像素位图,可以通过操作存储的像素位来编辑图片. QuartzCore这个框架是可移植的. 二.CGImageRef相关的一些方法解析 CFTypeID CGI

【转】VC的MFC中重绘函数的使用总结(整理)

原文网址:http://www.cnblogs.com/x8023z/archive/2008/12/09/mfc33.html 在刷新窗口时经常要调用重绘函数MFC提供了三个函数用于窗口重绘InvalidateRect(&Rect)Invalidate()UpdateWindow()当需要更新或者重绘窗口时,一般系统会发出两个消息WM_PAINT(通知客户区有变化)和WM_NCPAINT(通知非客户区有变化)--WM_NVPAINT系统会自己搞定--WM_PAINT消息对应的函数是OnPain

vc++图像保存,重绘

新建mfc应用程序,单文档 增加绘图 分别增加命令响应 添加成员变量UINIT 图形可以运行,如何保存呢?(一个集合类,CPtArt) 用一个类的对象来保存一个图形的三个要素 所以插入一个新的类(通常的类) 增加三个成员变量,第一个类型,设置为公有的 也可以在函数中直接写,添加起点,终点 让用户在构造的时候直接传递进来给这三个成员变量赋值 然后在原文件当中,对成员变量进行赋值 (这样构造一个类的对象来保存一个图形的三个要素) 要想增加一个指针用add,要想取出原数用GetAt CObArray

iOS 视图:重绘与UIScrollView(内容根据iOS编程编写)

我们继续之前的 Hypnosister 应用,当用户开始触摸的时候,圆形的颜色会改变. 首先,在 JXHypnosisView 头文件中声明一个属性,用来表示圆形的颜色. #import "JXHypnosisView.h" @interface JXHypnosisView () /** 颜色 */ @property (nonatomic,strong) UIColor * circleColor; @end @implementation JXHypnosisView - (in