Invalidate(TRUE)与Invalidate(FALSE)区别

篇一:

Invalidate(false)不擦除背景,直接画
Invalidate(true)擦除背景
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调用之后的语句。
UpdateData()顺便说下,这个函数不是刷新界面用的。
UpdateData();参数为FALSE时,将界面上控件绑定的变量的数据导到控件内,参数为TRUE时,导入方向则相反。

篇二:

使用Invalidate(TRUE)函数时,它会向消息队列中添加了WM_ERASEBKGND和WM_PAINT两个消息。

使用Invalidate(FALSE)函数时,它只会向消息队列中添加了WM_PAINT消息。

WM_ERASEBKGND消息的作用以背景色填充客户区,因此他会将之前绘制的图像情况,然后响应WM_PAINT消息后,会调用OnPaint函数,进行响应图像绘制工作。故Invalidate(TRUE)相当于将原来画的内容清空后,重新绘制。

而Invalidate(TRUE)只发送WM_PAINT消息,会调用OnPaint函数,进行响应图像绘制工作。故Invalidate(TRUE)的作用相当于在原来绘图的基础上继续画图。

打个比方:小明准备在黑板上画画,他准备画一只鸡和一只鸭

情形一:当画完小鸡后,小明觉得画的不像,于是将黑板擦擦除所画的小鸡,重新画。这相对于Invalidate(TRUE)函数的处理过程。

情形二:当画完小鸡后,小明觉得画得想当逼真,于是在此基础上继续画另一只鸭。这相对于Invalidate(FALSE)处理过程。

实验源码(对话框工程,在OnPaint函数中添加代码):

CPaintDC dc(this);  
int x = rand()%200;  
int y = rand() % 200;         
dc.Ellipse(CRect(CPoint(x, y), CSize(100, 100)));         
x = rand() % 200;  
y = rand() % 200;  
CBrush brush(RGB(0, 0, 255));  
dc.FillRect(CRect(CPoint(x, y), CSize(100, 100)), &brush);  
CPaintDC dc(this);
int x = rand()%200;
int y = rand() % 200;		
dc.Ellipse(CRect(CPoint(x, y), CSize(100, 100)));		
x = rand() % 200;
y = rand() % 200;
CBrush brush(RGB(0, 0, 255));
dc.FillRect(CRect(CPoint(x, y), CSize(100, 100)), &brush);

在OnInitDialog函数中设置定时器:

 

SetTimer(1, 1000, NULL);

添加WM_TIME消息响应,在OnTimer函数中添加:

Invalidate(TRUE);

运行结果:

 

在OnInitDialog函数中设置定时器:

 

SetTimer(1, 1000, NULL);

添加WM_TIME消息响应,在OnTimer函数中添加:

Invalidate(TRUE);

运行结果:

而将Invalidate(TRUE)改为:

Invalidate(FALSE);

运行结果为:

可见:Invalidate(FALSE)不会清空之前所画图像。

如果你想用Invalidate(TRUE)来实现Invalidate(FALSE)一样的效果,你可以添加对WM_ERASEBKGND消息响应的函数,修改OnEraseBkgnd函数为:

BOOL CaaDlg::OnEraseBkgnd(CDC* pDC)  
{  
    return TRUE;  
}  

BOOL CaaDlg::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}

此时Invalidate(TRUE)与Invalidate(FALSE)的效果是一样的。

实际应用:

/*Invalidate(); 整个界面刷新
Invalidate(TRUE); 整个界面背景刷新
Invalidate(FALSE); 整个界面背景局部刷新

InvalidateRect(CRect,TRUE);   选定区域刷新
UpDataWindows()*/

//实际操作相关代码如下
ITrainViewSizeStategy *pStategy = m_pMainFrame->m_cControlSizeStrategy.Get_ITrainViewSizeStategyPtr();	
	//面板显示控件	   
	CRect    rtModularBar  = pStategy->Get_Modular1ContainWndRegion();
	//脚本
	CRect    rtScriptSelBtn = pStategy->Get_ScripSelectButtonRegion();
	CRect    rtModularScriptSel;
	rtModularScriptSel.UnionRect(&rtModularBar,&rtScriptSelBtn);
	InvalidateRect(rtModularScriptSel,TRUE);

//控件区域大小函数如下:
//返回脚本选择按钮的位置区域
CRect C1280X768TVSizeStrategy::Get_ScripSelectButtonRegion()
{
	return CRect( CPoint(5,505), CSize(156,27) );
}

//返回面板1容器控件的位置区域
CRect C1280X768TVSizeStrategy::Get_Modular1ContainWndRegion()
{
	return CRect( CPoint(0,539), CSize(165,107) );
}

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值