博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MFC窗口重绘
阅读量:5838 次
发布时间:2019-06-18

本文共 3530 字,大约阅读时间需要 11 分钟。

 

Invalidate()与 UpdateAllViews()有什么分别

 

Invalidate()是让程序重画窗口。

UpdateAllViews()是在DOC/VIEW结构中,

当一个视图的数据改变后,

通知所有视图作相应的改变,

和重画毫无关系。

Invalidate()是使窗口无效,使系统向其发WM_PAINT消息,使的程序的OnPaint被调用重画客户区。

而UpdateAllViews()是文档与视之间的联系,调用从它会使程序与此文档相关的所有视的UpdateView被调用至于是否重画以及怎么画是由各视的UpdateView来决定的。

Invalidate()是Cwnd的成员函数,与DOC-VIEW无关;

UpdateAllViews是CDocument的成员函数,具体体现DOC-VIEW的精神。

如果仅重画当前窗口用 this->Invalidate();

如果通知所有和当前文档相关的窗口重画用GetDocument()->UpdateAllViews()(在View中)或this->UpdateAllViews()(在Doc中)。

Invalidate()函数产生一条WM_PAINT消息,并送入windows消息队列中,是窗口产生重画。

而,UpdateAllViews 并不进入windows消息队列中,直接产生重画

 

Invalidate函数的总结

 

 

InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效

InvalidateRect函数中的参数TRUE表示系统会在你画之前用背景色将所选区域覆盖一次,默认背景色为白色,可以通过设置BRUSH来改变背景色。

Invalidate()之后:(MFC的,顺便了)

OnPaint()->OnPrepareDC()->OnDraw()

所以只是刷新在OnPaint()和OnDraw()函数中的绘图语句。其它地方没有影响。

Invalidate标记一个需要重绘的无效区域,并不意味着调用该函数后就立刻进行重绘。类似于PostMessage(WM_PAINT),需要处理到WM_PAINT消息时才真正重绘。以为您Invalidate之后还有其他的语句正在执行,程序没有机会去处理WM_PAINT消息,但当函数执行完毕后,消息处理才得以进行。

Invalidate只是放一个WM_PAINT消息在队列里,不做别的,所以只有当当前函数返回后,进入消息循环,取出WM_PAINT,才执行PAINT,所以不管Invalidate放哪里,都是最后的。

InvalidateRect(hWnd,&rect,TRUE);向hWnd窗体发出WM_PAINT的消息,强制客户区域重绘制,

rect是你指定要刷新的区域,此区域外的客户区域不被重绘,这样防止客户区域的一个局部的改动,而导致整个客户区域重绘而导致闪烁,如果最后的参数为TRUE,则还向窗体发送WM_ERASEBKGND消息,使背景重绘,当然在客户区域重绘之前。

UpdateWindow只向窗体发送WM_PAINT消息,在发送之前判断GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送WM_PAINT

如果希望立即刷新无效区域,可以在调用InvalidateRect之后调用UpdateWindow,如果客户区的任一部分无效,则UpdateWindow将导致Windows用WM_PAINT消息调用窗口过程(如果整个客户区有效,则不调用窗口过程)。这一WM_PAINT消息不进入消息队列,直接由WINDOWS调用窗口过程。窗口过程完成刷新以后立刻退出,WINDOWS将控制返回给程序中UpdateWindow调用之后的语句。(windows程序设计第5版 P98)

UpdateData()顺便说下,这个函数不是刷新界面用的。

UpdateData();参数为FALSE时,将界面上控件绑定的变量的数据导到控件内,参数为TRUE时,导入方向则相反。

 

 

void UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL );

 

 

NULL if all views are to be updated.

 

 

 

 

Remarks

Call this function after the document has been modified. You should call this function after you call the member function. This function informs each view attached to the document, except for the view specified by pSender, that the document has been modified. You typically call this function from your view class after the user has changed the document through a view.

参数: pSender 修改文档的视图的指针。如果所有视图都被更新,则返回NULL。 

lHint 包含修改的信息。 
pHint 包含修改信息的对象指针。 
说明:
在文档修改之后调用这个函数。应在调用SetModifiedFlag之后调用。除了pSender指定的视图之外,函数通知与文档连接的各个视图   文档已被修改的消息。通常在用户通过视图改动文档后调用该函数。
除了发送视图外,这个函数为每个文档视图调用CView::OnUpdate ,并传递lHint和pHint值,使用这些参数将文档的修改情况传递给视图。可以使用lHint为信息编码,(或者)定义一个CObject派生类保存修改信息,并使用pHint传递一个该类对象。为优化视图更新,在CView派生类中可覆盖CView::OnUpdate成员函数。

 

 

在Doc类中调用Invalidate重绘mfc窗口!

获取视图指针,再用Invalidate即可重绘mfc窗口。

代码如下:

  CUABApp   *pApp=(CUABApp   *)AfxGetApp();   

  CMainFrame   *pMainFrame=(CMainFrame   *)pApp->m_pMainWnd;   

  CChildFrame   *pFrame=(CChildFrame   *)pMainFrame->GetActiveFrame();   

  CView   *pView=(CView   *)pFrame->GetActiveView();   

  pView->Invalidate();  

方法二:

 

POSITION pos = GetFirstViewPosition();

CView* pView = GetNextView(pos);

pView->Invalidate();

 

 

 

 

CWnd::OnPaint() 是CWnd类的成员函数,是WM_PAINT 消息的响应函数.当你调用CWnd::UpdateWindow(),CWnd::RedrawWindow()时, 或者窗口被其他窗口覆盖,改变大小等事件就会产生WM_PAINT 消息. 你可以在CWnd派生的子类中使用它.

CView::OnDraw()是CView类的一个纯虚函数.你要使用,必须重载它.

CView::OnPaint()会调用它.

OnPaint是收到WM_PAINT消息时所调用的,OnPaint调用OnDraw函数,而由于OnDraw是虚拟函数,你可以自己改写,所以就实现了,不同的绘图目的

ondraw用于cview,而onpaint用于cdialog

onpait 响应WM_PAINT消息,在CView中,它接着调用OnDraw

CPaintDC响应wm_paint消息,自动完成绘制

ClientDC实时绘制

一般情况下,你看不到两个函数有什么太大区别,因为一般情况下,它们的任务都是重画窗口。

在CView及其子类中,恰如浪刀所言,OnDraw是由OnPaint调用的,也就是你可以像在窗口类中一样,调用Invalidate函数导致,OnDraw的调用(当然,Invalidate是先导致OnPaint的调用)。

要说OnDraw和OnPaint有什么区别,那就是它除了可以把画画到屏幕外,还可以把它画到其它任何标准输出设备,如打印机

转载地址:http://vxjcx.baihongyu.com/

你可能感兴趣的文章
前端那些事之React篇--helloword
查看>>
ios的google解析XML框架GDataXML的配置及使用
查看>>
netty-当一个客户端连接到来的时候发生了什么
查看>>
PHP_5.3.20 源码编译安装PHP-FPM
查看>>
在51CTO三年年+了,你也来晒晒
查看>>
js控制图片等比例缩放
查看>>
Java高级开发工程师面试考纲
查看>>
FreeMarker表达式
查看>>
Debian9.2 下使用vnstat查看服务器带宽流量统计
查看>>
NGINX + PHP-FPM 502
查看>>
mysql数据备份与恢复
查看>>
Openstack API常用命令
查看>>
OpenSSL漏洞凶猛来袭 慧眼恶意代码监测应对有方
查看>>
C语言 喝汽水问题
查看>>
LINUX中搭建DNS服务器,实现正向、反向以及访问不同DNS解析
查看>>
SCCM2012 R2实战系列之十:解决WDS服务无法启动问题(错误1067:进程意外终止)...
查看>>
怎么防止重复发送Ajax
查看>>
ubuntu 下安装 mysql
查看>>
关于k-means聚类算法的matlab实现
查看>>
Git分支2
查看>>