2 Windows虽然会发送WM_PAINT但是他并不一定会要求重绘全部的内容,如果你只更改的一点大小,那么Windows发送WM_PAINT的时候你通过BeginPaint(该API函数由MFC自动调用)获得的失效区域就只有这个大小,而即便你在OnDraw里面画了整个区域,也只有失效的区域是会被Windows更新到显示器上去,其他的部分它就直接忽略了。原因就是因为绘图相对其他计算比较慢,所以能不多画就不多画。在MFC中,通过CDC::GetClipBox可以获得本次绘图的失效区域,如果你绘图内容很多,就需要根据失效区域来选择性的绘图,不需要绘全部,否则可能会很慢。
3 Windows会自动在一些情况下设置失效区域,比如你从最小化还原窗口的时候,它设置整个客户区都失效,你改变大小的时候,它设置影响到的部分失效。你在程序里面也可以自己设置失效区域,Invalidate设置整个客户区都失效,InvalidateRect设置一部分失效,失效的部分会Windows在下一次发送WM_PAINT的时候更新。所以认为Invalidate是让窗口重绘是不对的,有可能发生你Invalidate之后窗口根本就没有重绘,因为Windows可能觉得没必要发送WM_PAINT,因为WM_PAINT是优先级比较低的消息,Windows优先发送其他消息。
4 如何强迫Windows立刻发送一个WM_PAINT 通过调用UpdateWindow,UpdateWindow做两个事情,首先他检查当前窗口是不是有失效的区域,若有它就立刻发送WM_PAINT,若没有它什么也不做。所以很多时候,可以看到,更新窗口的代码是两条连在一起的:
Invalidate(TRUE);
UpdateWindow();
Invalidate的参数告诉Windows是否需要在发送WM_PAINT之前发送WM_ERASEBKGND,该消息负责重画客户区背景。默认的是画成白色。
5 你也可以手工设定某个区域有效,通过ValidateRect即可。在你运行完OnDraw之后,MFC会自动调用EndPaint函数,该函数会自动将客户区全部设为有效。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)