1. 当WM_PAINT不是由InvalidateRect产生时,即由最大化,最小化等产生时,或者移动产生(移动有时只会产生WM_ERASEBKGND消息)系统先发送WM_ERASEBKGND消息,再发送WM_PAINT消息.

如果处理WM_ERASEBKGND消息时返回FALSE,BeginPaint标记pt.fErase 为TRUE,如果处理WM_ERASEBKGND时返回TRUE,BeginPaint标记pt.fErase为FALSE.

2.当WM_PAINT由InvalidateRect产生时,先发送WM_PAINT消息(异步),如果InvalidateRect的bErase为TRUE,BeginPaint检查到更新区域需要删除背景,向窗口发送一个WM_ERASEBKGND消息,如果处理WM_ERASEBKGND消息时返回FALSE,BeginPaint标记pt.fErase 为TRUE,如果处理WM_ERASEBKGND时返回TRUE,BeginPaint标记pt.fErase为FALSE.

如果pt.fErase标记为TRUE,指示应用程序应该处理背景,但是应用程序不一定需要处理,pt.fErase只是作为一个标记.

补充:DefWindowProc(hWnd, message, wParam, lParam)处理WM_ERASEBKGND消息时默认用下面的画刷清除背景
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

WM_ERASEBKGND返回TRUE和返回FALSE是一个规范,一般情况下没有什么区别,但是如果什么时候用到了,会根据函数返回值判断后续处理。因此最好按照要求返回数据.

http://note.sdo.com/u/432181446/NoteContent/pMF36~jDXzSFnM1rg001sf

------------------------------------------------------------------------------------------

当WM_PAINT不是由InvalidateRect产生时,即由最大化,最小化等产生时,或者移动产生(移动有时只会产生WM_ERASEBKGND消息)系统先发送WM_ERASEBKGND消息,再发送WM_PAINT消息.

当WM_PAINT由InvalidateRect产生时,先发送WM_PAINT消息,OnPaint()这个执行内部向窗口发送了 WM_ERASEBKGND消息来刷新背景。在OnPaint()函数中会首先调用BeginPaint()函数,在BeginPaint 函数中会发送WM_ERASBKGND.
OnEraseBkgnd函数内部不要使用 UpdateWindow MoveWindow SetWindowPos RedrawWindow等引起调用wm_paint的函数,如果在 OnEraseBkgnd 函数处理过程中 产生了需要刷新的无效区,导致系统产生wm_paint消息,这样就产生了死循环!

要在程序中想要把背景色设置成其他颜色(不是默认的),那这个代码一般在WM_ERASEBKGND 的消息响应函数中执行,而当我们想在界面上画个图形之类的,一般在WM_PAINT的消息响应函数如OnPain中执行。凡事无绝对,就是你也可以把 背景的设置放在OnPain中绘制

WM_ERASEBKGND如果返回非0,说明已经重画背景,如果返回0,程序将继续试图重画背景。

 
http://qiusuoge.com/10860.html
------------------------------------------------------------------------------------------

问题:Windows系统没有发出WM_ERASEBKGND消息
根据MSDN的描述,当windows被最小化时,系统需要绘制icon。
通常,系统会首先发送WM_ICONERASEBKGND给窗口,然后再发送WM_PAINTICON消息给窗口。MSDN又说,如果应用程序的WNDCLASS结构的hIcon成员如果为NULL,那么系统会发送WM_ERASEBKGND消息来替代
WM_ICONERASEBKGND消息,然后再发送WM_PAINT消息。为此应用程序应该在自己的代码中,
通过IsIconic()函数来判断当前是否application处于miminized状态。如果是,那么在
其OnEraseBkGnd函数和OnPain函数中都应该根据其minimized状态来绘制图标背景和图标。当然,MFC程序会封装WNDCLASS结构,为此我们看不到RegisterClass函数。为此我通过
GetClassInfo函数来获取WNDCLASS结构,结果发现hIcon域为NULL。根据MSDN的描述,在窗口minimized的情况下,系统应该会发出WM_ERASEBKGND消息,但是我通过
打印TRACE信息发现,系统根本没有在minimized情况下发出WM_ERASEBKGND消息。另外,根据MSDN的描述,WM_ICONERASEBKGND消息仅仅在Windows NT 3.51 and earlier有效。请高手指点,谢谢!!

The WM_ERASEBKGND message is sent when the window background must be erased (for example, when a window is resized). The message is sent to prepare an invalidated portion of a window for painting.
-------------
个人觉得最小化(IsIconic函数调用为TRUE),图标化了,就没有必要发送WM_ERASEBKBND消息来绘制窗口背景,可能是为了效率。

刚刚搜索到一个老外的描述:他说IsIconic是win16和NT3.x以前的东西,现在已经可以不需要这个分支了。另外,在百度上看到这篇文章:觉得分析得有道理。当窗口最小化时,此时已经不需要绘制client area,为此不会发出WM_PAINT消息。实际上,仅仅当application client area有update region时,系统才会在message queue为空时,才会发出WM_PAINT消息。而当application接收到WM_PAINT消息时,会首先调用BeginPaint函数来准备display device context(在CDialog::OnPaint => CPaintDC dc(this)构造函数之中),如果update region被标记为erasing,那么BeginPaint又会发出WM_ERASEBKGND消息。为此,既然在最小化时系统没有发送WM_PAINT消息给窗口,为此更不会发出WM_ERASEBKGND消息。
我曾在最小化时,故意发出WM_PAINT消息,此时该消息会进入到OnPaint的IsIconic分支。但是,如果你故意发出WM_ERASEBKGND消息,那么该消息必须在Cdialog::OnSysCommand函数之前,否则会被系统丢弃,为此不会进入OnEraseBkGnd函数。

谢谢VisualEleven的回复,系统确实为了优化client area operation而限制了某些不必要消息的发送。

http://www.debugease.com/vc/1246693.html

------------------------------------------------------------------------------------------

请问MFC的一个代码简单却功能奇怪的问题?
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
上面这个代码是MCF向导自动生成的,我跟踪了一下在最小化,最大化的过程发现没有被执行到,去掉 发现出也没出现什么不同,为何MFC要默认的帮我们生产上面的代码,有哪位高手知道上面的代码正真的目的是什么?在什么情况下会被执行到?

这段代码是有用的,尽管通常情况下不会被调用。他的作用是在最小化状态下重绘窗口图标。

IsIconic()作用是判断窗口是否处于最小化状态(点击了最小化按钮之后)。

对于普通的对话框来说,如果你在if (IsIconic()) 下面加入AfxMessageBox("haha") ,你会发现消息框并不会弹出。

原因是,if (IsIconic()) 这段代码是在OnPaint()函数内,当你最小化了对话框之后,虽然IsIconic()的值是TRUE,但是OnPaint()函数并不会运行。因为OnPaint()响应的是WM_PAINT消息,而WM_PAINT消息是针对客户区的。一个最小化了的窗口不需要重绘客户区。

为了验证这一点,可以设置一定时器,在OnTimer()函数里写上
if(IsIconic()) MessageBeep(MB_OK);
当你点击最小化按钮后,你会听见嘟嘟声。

那么这段代码究竟有什么用?它是不是永远不会被执行呢?当然不是。举两个例子。
第一,如果你强行发送WM_PAINT消息,它会执行。
第二,特殊的对话框。比如一个ToolBox风格的对话框。这个对话框不显示在任务栏,在最小化之后它会变成一个很小的一条显示在桌面上。这时如果它被遮挡,就会出发WM_PAINT消息,从而执行那段代码。

总之,一般情况下可以不要这段代码,它的特殊用途我也不是很了解,但是我们至少可以知道它是怎么样工作的。

http://zhidao.baidu.com/question/50297340

------------------------------------------------------------------------------------------
 
 

WM_PAINT产生原因有2种(用户操作和API)——WM_PAINT和WM_ERASEBKGND产生时的先后顺序不一定(四段讨论)的更多相关文章

  1. WM_PAINT与WM_ERASEBKGND(用户操作和API这两种情况产生消息的顺序有所不同)

    1)当WM_PAINT不是由InvalidateRect产生时,即由最大化,最小化等产生时,或者移动产生(移动有时只会产生WM_ERASEBKGND消息)系统先发送WM_ERASEBKGND消息,再发 ...

  2. 终于懂了:WM_PAINT 与 WM_ERASEBKGND(三种情况:用户操作,UpdateWindow,InvalidateRect产生的效果并不相同),并且用Delphi代码验证 good

    一直对这两个消息的关系不是太了解,借重新深刻学习windows编程的机会研究一番. 1)当窗口从无效变为有效时,比方将部分覆盖的窗口恢复时会重绘窗口时:程序首先会通过发送其他消息调用DefWindow ...

  3. Entity Framework 实体框架的形成之旅--几种数据库操作的代码介绍(9)

    本篇主要对常规数据操作的处理和实体框架的处理代码进行对比,以便更容易学习理解实体框架里面,对各种数据库处理技巧,本篇介绍几种数据库操作的代码,包括写入中间表操作.联合中间表获取对象集合.递归操作.设置 ...

  4. jQuery中模拟用户操作

    有时为了节省不想手动操作网页,但又想看到用户操作时的效果,可以用到jQuery提供的trigger方法.见下图代码 在不点击按钮时仍然想弹出this.value 我们只需要在后面加上.trigger( ...

  5. 关于Linux 交互(用户操作接口)

    Linux 系统提供两种基本接口给用户操作:命令行,图形界面. 不同接口也有相应的访问终端. 一.命令行 Command Line Linux系统命令行,一般指 Shell. Shell 接受经键盘输 ...

  6. 从知乎首页用户操作入口学习到的CSS技巧 - 合理利用伪元素实现一些装饰样式

    最近在模仿做一个静态的PC版知乎,在模仿的过程中,从知乎工程师的方法中学到了不少知识,比如CSS方面的,以下介绍一个今天学到的伪元素的技巧. 示例 DOM结构为: <div class=&quo ...

  7. Linux下ftp安装配置及三种用户的验证

    一.原理简介 二.安装配置 三.三种用户的验证 一.简介 FTP即文件传输协议(File Transfer Protocol),完成各主机的文件共享功能,基于客户端-服务器的协议,工作在应用层,tcp ...

  8. C#路径的八种相关操作,判断字符串是否为路径等

    原文:C#路径的八种相关操作,判断字符串是否为路径等 1.判定一个给定的C#路径是否有效,合法 通过Path.GetInvalidPathChars或Path.GetInvalidFileNameCh ...

  9. linux下用户操作记录审计环境的部署记录

    通常,我们运维管理人员需要知道一台服务器上有哪些用户登录过,在服务器上执行了哪些命令,干了哪些事情,这就要求记录服务器上所用登录用户的操作信息,这对于安全维护来说很有必要.废话不多说了,下面直接记录做 ...

随机推荐

  1. 一天一个类--ArrayList之二

    继续我的小激动--- 1.看看构造一个ArrayList 有两种方式 一个指定大小,一个不指定.我们知道他其实使用数组来实现了,数组肯定要有大小,那么他没指定大小,默认的是多少呢???追踪源码---开 ...

  2. 动态规划之一ones

    n给一个整数n,要你找一个值为n的表达式,这个表达式只有1 + * ( ) 够成.并且1不能连续,比如11+1就不合法. n输入n,(1<=n<=10000) n输出最少需要多少个1才能构 ...

  3. cocos2d-x游戏开发系列教程-中国象棋00-前言

    象棋描述 在说代码之前,我们先让象棋效果登场,以方便大家对代码的理解 欢迎界面 中国象棋程序,运行起来的第一个界面是一个欢迎界面,该欢迎界面在停留一秒后进入游戏界面 游戏主界面 新局:所有棋子归位,状 ...

  4. Boost::filesystem 使用小笔记

    今天拿起手要用C++写个小工具,从指定的目录递归遍历文件,然后做一下处理.又翻了一下boost的filesystem库.小结一下,希望能加深印象,免得下次又要查看文档. 1. path对象就是一个跨平 ...

  5. 织梦sitemap模板获取文章列表

    分析了一下makehtml_map.php?dopost=site这个文件,发现生成视图用的是dedetag.class.php文件,有点简单.不能使用织梦的很多标签,例如: {dede:arclis ...

  6. 怎样在android实现uc和墨迹天气那样的左右拖动效果

    import android.app.Activity; import android.os.Bundle; import android.content.Context; import androi ...

  7. Ajax技术——带进度条的文件上传

    1.概述 在实际的Web应该开发或网站开发过程中,经常需要实现文件上传的功能.在文件上传过程中,经常需要用户进行长时间的等待,为了让用户及时了解上传进度,可以在上传文件的同时,显示文件的上传进度条.运 ...

  8. WM_PAINT消息在窗口重绘的时候产生,那什么时候窗口会重绘(异步工作方式效率高、灵活性强,还有UpdateWindow和RedrawWindow帮忙)

    Q:wm_paint消息在窗口重绘的时候产生,那什么时候窗口会重绘?? A: 严格地说,只有当收到WM_PAINT消息后窗口会重绘 但是引起这个消息的事件有很多, 比如:1.首次创建 2.移动 3.改 ...

  9. VC Office2007界面对话框实现

    我们知道VS2008SP1之后,MFC就多了一个功能包,可以快速的建立一个ribbon的界面,视觉样式可以在office 2007蓝.黑等颜色之间切换,这对于单文档/多文档做界面非常方便,而且也蛮好看 ...

  10. LoadRunner 监控 Apache

    配置Apache部分 1.修改Apache中Httpd.conf文件 <Location /server-status> SetHandler server-status Order de ...