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

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 ComboxBox重绘类

    在这个场景中,我们关注的是`CMyComboBox`,这是一个自定义的组合框(ComboBox)类,它是MFC中的标准`CComboBox`类的扩展,专门为了实现自定义重绘功能而设计。 在MFC中,`CComboBox`类是用来处理Windows API中的...

    Mfc实现Edit重绘

    本文将深入探讨如何在MFC中实现Edit控件的重绘,包括编辑框的边框处理、文字居中、非客户区与客户区的绘制,以及针对VS2010中黑影问题的解决方案。 1. **Edit控件的边框重绘** 在MFC中,我们可以利用消息映射机制...

    MFC 基本常用控件重绘

    在本文中,我们将深入探讨如何在MFC中重绘常见的控件,包括ListCtrl、Edit和ComboBox,这些都是Windows应用程序开发中的关键组件。 **ListCtrl控件** ListCtrl是一种多功能控件,它可以显示多列数据,类似于电子...

    MFC中 重绘CListCtrl控件,自定义

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

    MFC CListCtrl重绘,功能全

    在Windows应用程序开发中,...总之,MFC CListCtrl的重绘是一项深度定制功能,允许开发者实现各种复杂、美观的界面效果。通过理解和熟练运用重绘机制,我们可以创造出极具个性化的用户界面,提升应用的用户体验。

    MFC树控件重绘

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

    MFC控件重绘MFC控件重绘

    MFC控件重绘是一个关键的概念,涉及到UI的定制和美化。本篇文章将深入探讨MFC控件重绘的过程、方法以及相关技术。 首先,我们了解什么是控件重绘。在Windows系统中,每个控件都有一个默认的绘制方式,但有时为了...

    MFC各种重绘漂亮按钮

    本文将深入探讨如何使用MFC来创建和重绘漂亮的按钮,主要基于提供的资源“BeauButton”。 在Windows用户界面设计中,按钮是一种基本且不可或缺的控件。默认情况下,Windows系统提供的按钮样式相对朴素。然而,通过...

    MFC CButton按钮重绘(GDI篇)

    本文将深入探讨如何使用GDI(Graphics Device Interface)在MFC中重绘CButton控件,以及如何实现不规则形状的PNG图片按钮。 首先,了解GDI是Windows图形绘制的核心,它提供了一系列函数来创建、管理以及操作图形...

    MFC 重绘CListCtrl、CTreeCtrl的滚动条

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

    MFC控件CTabCtrl的重绘,支持背景颜色、tab头字体颜色、背景色的修改

    总结来说,通过MFC的CTabCtrl控件的派生和重绘技术,我们可以轻松实现自定义的背景颜色、字体颜色以及突出显示当前选中的tab。这个过程涉及到了Windows消息处理、图形绘制和控件的动态更新等多方面的知识,有助于...

    MFC图形重绘

    在Microsoft Foundation Classes (MFC)库中,图形重绘是一个重要的概念,用于更新应用程序的用户界面,确保在窗口内容发生变化时能够正确显示。MFC是微软为Windows平台提供的一套C++类库,它简化了Windows API的使用...

    MFC的CheckBox自绘类

    MFC的CheckBox类是用于创建和管理复选框控件的,而“MFC的CheckBox自绘类”则是对这个标准控件的扩展,旨在提供更丰富的视觉效果和功能。 在标准的MFC CheckBox中,控件的外观主要由操作系统定义,样式相对固定。...

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

    标题"**MFC 重绘CListCtrl、CTreeCtrl的滚动条.rar**"提供的资源正是针对这个需求,实现了滚动条的自定义重绘,以达到与控件完美融合的效果。 滚动条控件在MFC中由CScrollBar类表示,通常会与CListCtrl和CTreeCtrl...

    自绘/重绘MFC右键菜单CMenu

    本篇文章将详细讲解如何在MFC应用中实现自绘或重绘右键菜单CMenu,以创建更具个性化的用户界面。 自绘(Custom Draw)或重绘(Redraw)是指在系统默认渲染的基础上,程序员通过调用特定的API函数或MFC类的方法来...

    MFC SliderCtrl重绘

    本篇文章将深入探讨如何在MFC中重绘SliderCtrl,以及解决GDI资源泄露问题。 首先,我们需要了解SliderCtrl的基本使用。在MFC中,SliderCtrl通常是CSliderCtrl类的一个实例。你可以通过在对话框资源编辑器中添加一个...

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

    本文将深入探讨如何使用MFC来重绘这些元素,并特别关注在尝试改变状态栏背景色时遇到的问题。 首先,让我们了解MFC中的窗口部件。标题栏是窗口顶部显示应用程序名称和最小化、最大化、关闭按钮的部分。菜单栏通常...

    MFC 之 CButton 控件重绘(GDI+篇)

    本文将深入探讨如何利用MFC中的CButton控件,并结合GDI+技术来实现不规则形状和透明效果的按钮重绘。 首先,让我们了解CButton控件。它是MFC库中一个基本的用户界面元素,用于创建具有标准按钮功能的窗口。默认情况...

Global site tag (gtag.js) - Google Analytics