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. WPF常用转换

    原文 WPF常用转换 以下是代码中常常用到的一些转换,整理如下,后续再不断完善: 1.string和Color的转换 //string转Color (Color)ColorConverter.Conv ...

  2. asp.net 通过 Handler 导出数据至excel (让用户下载)

    效果图: 代码: Export2Excel.ashx <%@ WebHandler Language="C#" CodeBehind="Export2Excel.a ...

  3. CCIE路由实验(7) -- MPLS VPN

    1.LDP协议的各种情况2.LDP和BGP交互3.LDP高级部分4.MPLS VPN (RIP和静态)5.MPLS VPN (EIGRP)6.MPLS VPN (OSPF)7.MPLS VPN (EB ...

  4. ESRI Shapefiles (SHP)

    ESRI Shapefiles (SHP) Also known as ESRI ArcView Shapefiles or ESRI Shapefiles. ESRI is the company ...

  5. GTest交流与经验总结

    GTest交流与经验总结 原文见:   http://starsourcingsolutions.com/myblog/?p=159

  6. IOS开发之UILabel动态高度设置方法

    项目中有这样的需求,要显示一本书的概述,默认显示2行,点击展开按钮,显示全部,点击收回,有显示2行. 开始的时候按钮事件中,可能写的是这样一段代码: if (isExpand) { [lblBrief ...

  7. C# - 线程操作

    代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...

  8. oracle忘记密码,修改密码,解锁

    忘记密码修改密码: alter user system identified by values abc111; 修改后的用户名system,密码abc111. 解锁: cmd->输入 :sql ...

  9. 小W与网格

    lucas定理 http://www.cnblogs.com/vongang/archive/2012/12/02/2798138.html 题目:http://hihocoder.com/conte ...

  10. Qt 多线程 详细函数说明及其事例

    转:http://www.cnblogs.com/hicjiajia/archive/2011/02/03/1948955.html Qt线程类 Qt 包含下面一些线程相关的类:QThread 提供了 ...