您的位置:首页 > 其它

InvalidateRect()、UpdateWindow()、RedrawWindow()区别

2011-09-27 14:55 295 查看
先看一段移动图片的程序:

绘图工作都在ReDraw()中

响应MouseMove 改变图片的位置,鼠标移动后需要重绘窗口

实验一: ReDraw()在MouseMove函数中调用

OnMouseMove(UINT nFlags, CPoint point)
{
。。。

ReDraw();
InvalidateRect(m_ClientRect);
。。。
}
试验发现: 鼠标移动时,图片移动不连贯,也就是说窗口没有实时重绘,而是每隔不定的时间重绘一次,这样图片移动时给人磕磕绊绊、很不顺畅的感觉。


试验二: ReDraw()在OnDraw函数中调用

OnDraw(CDC* pDC)
{

...
ReDraw();

...
}


OnMouseMove(UINT nFlags, CPoint point)
{
。。。

//ReDraw();  注释掉ReDraw(),仅使用InvalidateRect()
InvalidateRect(m_ClientRect);
。。。
}

试验发现:图片能够随鼠标实时移动,也就是说窗口得到了实时更新

那问题自然就来了:为什么两个试验,结果迥然?

要说InvalidateRect()不能马上更新窗口,那为什么试验二的效果看起来如立即更新一样?

据我分析,可能的原因是这样的:

首先,InvalidateRect()不能马上更新窗口,而是将更新消息WM_PAINT放在消息队列中,在实验二中,消息队列中的消息很少,所以很快便执行到了WM_PAINT,而实验一中,在InvalidateRect()之前还要执行ReDraw(),执行ReDraw()需要一段时间,这段时间,因为鼠标一直移动,所以一直将鼠标移动消息放入消息队列中,因此,WM_PAINT前的消息多,所以便出现了图片移动不连贯的现象。

试验三 :ReDraw()放入MouseMOVE函数中 使用UpDateWindow()

OnMouseMove(UINT nFlags, CPoint point)
{
。。。
ReDraw();
UpdateWindow();

。。。
}


按相关资料说:UpdateWindow()可以立即更新窗口,那么这下应该没有问题了吧!

可是,试验显示,鼠标移动时,图片稳如磐石,丝毫不动。而只有窗口最小化然后最大化需要重绘时,图片才显示到鼠标所在的位置

怎么回事?怎么回事呀,资料上不是说UpdateWindow()立即更新窗口吗?怎么试验结果好像差之千里。。。

别急: 先找找原因。

诚然,UpdateWindow() 可以实现立即更新,但是它是有前提的。

什么?没找到前提条件?只看到资料说立即更新?---------这就是不完善的资料造成的后果

额。。。-----还有一种就是明明资料上有介绍,是自己忽视了

UpdateWindow() 可以实现立即更新,但是它的前提是:先让需要更新的区域失效。

试验四: 使用UpdateWindow()更新窗口

OnMouseMove(UINT nFlags, CPoint point)
{
。。。
ReDraw();
InvalidateRect(m_ClientRect); //先将需要更新的区域 用InvalidateRect失效掉,然后再UpdateWindow()

UpdateWindow();

。。。
}


结果显示: 图片移动连贯,可以实现立即更新

试验五: 使用RedrawWindow()

OnMouseMove(UINT nFlags, CPoint point)
{
。。。
ReDraw();
RedrawWindow(m_ClientRect);

。。。
}


结果显示:图片移动连贯,可以立即更新窗口

RedrawWindow(m_ClientRect); 效果相当于InvalidateRect(m_ClientRect); UpdateWindow();

BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL,
CRgn* prgnUpdate = NULL,
UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);


这是 RedrawWindow()的定义,由此得知:默认参数情况下是立即更新窗口

RedrawWindow(rect) 相当于:

RedrawWindow(m_ClientRect,NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);


总结:

由以上五个例子分析了三者之区别,简言之,InvalidateRect()不能实现立即更新 ,

但是InvalidateRect()与 UpdateWindow()结合后可以实现立即更新,

两者结合的效果相当于RedrawWindow(rect)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: