`
java-mans
  • 浏览: 11386759 次
文章分类
社区版块
存档分类
最新评论

MFC之口重绘

 
阅读更多

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的一个作用就是把该Update Region置为空,这样如果不调用BeginPaint,窗口的Update Region就一直不为空,如前所述,系统就会一直发送WM_PAINT消息。
BeginPaint和WM_ERASEBKGND消息也有关系。当窗口的Update Region被标志为需要擦除背景时,BeginPaint会发送WM_ERASEBKGND消息来重画背景,同时在其返回信息里有一个标志表明窗口背景是否被重画过。当我们用InvalidateRect和InvalidateRgn来把指定区域加到Update Region中时,可以设置该区域是否需要被擦除背景,这样下一个BeginPaint就知道是否需要发送WM_ERASEBKGND消息了。

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

以下是Invalidate函数的作用::
void Invalidate( BOOL bErase = TRUE );
该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无 效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数 OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw 来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。
和 UpdateWindow( )区别在于:UpdateWindow( )的作用是使窗口立即重绘。调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消 息发送完后才能被处理。调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘.

分享到:
评论

相关推荐

    MFC控件重绘MFC控件重绘

    MFC控件重绘MFC控件重绘MFC控件重绘MFC控件重绘

    MFC ComboxBox重绘类

    MFC,ComboxBox,重绘代码类 MFC,ComboxBox,重重绘代码类

    Mfc实现Edit重绘

    mfc中实现Edit控件重绘,包括Edit的悬停边框、文字居中,绘制Edit的非客户区和客户区等。但是有个问题我一直没有解决,就是VS2010中存在.manifest文件时,编辑框上有黑影。

    MFC中 重绘CListCtrl控件,自定义

    这是一个MFC 重绘CListCtrl的方法,简单易懂。 有薛MFC 做UI的同学可以使用。 还可以设置行高,颜色,标题栏高度等属性。 还可以排序。

    MFC 基本常用控件重绘

    该项目需要使用VS2008来打开,项目主要是对一些基本常用的控件进行重绘,包含有ListCtrl控件、Edit控件、Combox控件...一些基本的控件

    MFC ProgressCtrl重绘

    MFC ProgressCtrl 进度条重绘 增加了点击进度条 到达指定位置

    MFC普通窗口重绘

    MFC普通窗口重绘,有什么不懂的可以随时到我的博客留言http://www.gymsaga.com/,我会尽早解答您的问题,更多MFC实例讲解,请登陆我的博客。

    MFC图形重绘

    MFC 图形重绘 c++ MFC

    MFC绘制皮肤-界面重绘

    MFC绘制皮肤 界面重绘MFC绘制皮肤 界面重绘MFC绘制皮肤 界面重绘MFC绘制皮肤 界面重绘MFC绘制皮肤 界面重绘

    MFC CListCtrl重绘,功能全

    MFC CListCtrl 重绘 c++ 功能全 效果拍漂亮 MFC CListCtrl 重绘 c++ 功能全 效果拍漂亮

    MFC 重绘CListCtrl、CTreeCtrl的滚动条

    这是我见过、用过的最好的一个有关重绘CListCtrl滚动条的代码。需要了联系345271592,我直接发你们。资源中外面的两个代码文件我只是将源程序中加载应用中的资源改为加载本地资源而已,在此感谢...

    MFC树控件重绘

    使用Onpaint 重绘树控件,树控件图片动态载入,达到了一般聊天工具基本功能(大小头像的转换,浮动提示框,鼠标移动改变背景色,姓名和心情同行不同字体格式等一些功能),现在与大家一起分享,绝对值5分,保证你不...

    MFC重绘标题栏、菜单栏并更改状态栏背景色

    MFC重绘标题栏、菜单栏并更改状态栏背景色。工具栏背景色未修改成功!

    MFC重绘Button为圆形。

    MFC中重绘Button为圆形Button,可以修改背景颜色、文本颜色、边框颜色等。

    MFC 重绘CListCtrl、CTreeCtrl的滚动条.rar

    MFC 重绘CListCtrl、CTreeCtrl的滚动条,实现了添加滑动条控件的背景重绘,完全和控件完美的结合在一起,用当前的控件可以直接应用到你的项目进行二次开发,非常好的资源。

    MFC SliderCtrl重绘

    重绘SliderCtrl 可以自行更改颜色大小等 修正了原本的GDI资源泄露问题

    重绘MFC列表控件(ListCtrl)字体 表头和行高度 行颜色等

    重绘MFC列表控件(ListCtrl)字体大小 表头和行高度 行颜色等 行的颜色有5中:选中(获取焦点和丢失焦点2种),未选中(鼠标移动时、奇行和偶行)等

    MFC CButton按钮重绘(GDI篇)

    该工程为VS2010工程,里面有3类自绘按钮,其中利用PNG图片来简单实现了不规则按钮。

    MFC的CheckBox自绘类

    一个MFC实现的CheckBox自绘类,支持动态加载PNG图标

Global site tag (gtag.js) - Google Analytics