WM_PAINT 和 WM_ERASEBKGND 消息的区别
2012-10-30 16:00
267 查看
先看看,如何获得HDC(设备句柄)
1.调用BeginPaint()。绘制范围是窗口的无效区域。通常是在WM_PAINT中调用。这个api获得HDC,在EndPaint()以后,会将窗口的无效区域置为有效区域。BeginPaint()会根据Invalidate()时传的参数,决定是否擦除背景。需要擦除背景时,BeginPaint()会发送一个WM_ERASEBKGND。
2.调用GetDC()和GetWindowDC(),获得的HDC,绘制范围是整个窗口。且在ReleaseDC()后,不会设置窗口的无效区域为有效(确切地说这种方式获得的dc,整个窗口都可以绘制,其无效区域是整个窗口)。可以在任意地方获取这个dc并绘图。
一个常见的疑惑是,在窗口重绘时,先发WM_PAINT还是先发WM_ERASEBKGND消息?答案是都有可能。
1.由于移动窗口,改变窗口,最大最小化窗口,导致的重绘。系统会先发WM_ERASEBKGND消息,后发WM_PAINT消息(此时OnPaint函数的wparam是一个hdc)。
2.由于调用了Invalidate()或InvalidateRect()导致的重绘。系统会发WM_PAINT消息。在处理WM_PAINT消息,通常会调用BeginPaint()(此时wparam是NULL)获得HDC。BeginPaint()会根据需要,决定是否发送WM_ERASEBKGND。
在看几个应用中的问题。
1.OnErasebkgnd()中,返回真表示已经擦除了背景,返回假表示没有擦除背景。这个返回值,只对BeginPaint()的第二个参数(这是一个传出型参数)PAINTSTRUCT的fErase有影响。OnErasebkgnd()返回假时,fErase被BeginPaint()设置为真,表示下面应该考虑擦除背景的事。
2.WTL中CPaintDC构造函数中会调用BeginPaint()获得dc,析构函数中会调用EndPaint()。
在做窗口界面优化的时候,正确的处理WM_PAINT和WM_ERASEBKGND是很重要的,不管是先产生WM_ERASEBKGND还是WM_PAINT.
在处理OnPaint时采用如下方法:
PAINTSTRUCT PS;
HDC hdc = BeginPaint(&PS);
做相关GDI操作
EndPaint(&PS);
处理OnEraseBkgnd时采用如下方法:
return 1;
第一种情况(WM_PAINT消息产生在前,WM_ERASEBKGND消息产生在后)
BeginPaint会检测是否删除背景,如果是,发送WM_ERASEBKGND(当WM_PAINT手动(由InvalidateRect等函数)产生时)
第二种情况(WM_PAINT消息产生在后,WM_ERASEBKGND消息产生在前)
在处理WM_PAINT之前已经处理了WM_ERASEBKGND
如果处理WM_ERASEBKGND消息时返回FALSE,BeginPaint标记pt.fErase 为TRUE,如果处理WM_ERASEBKGND时返回TRUE,BeginPaint标记pt.fErase为FALSE.WM_ERASEBKGND返回TRUE和返回FALSE是一个规范,一般情况下没有什么区别,但是如果什么时候用到了,会根据函数返回值判断后续处理。因此最好按照要求返回数据.
1.调用BeginPaint()。绘制范围是窗口的无效区域。通常是在WM_PAINT中调用。这个api获得HDC,在EndPaint()以后,会将窗口的无效区域置为有效区域。BeginPaint()会根据Invalidate()时传的参数,决定是否擦除背景。需要擦除背景时,BeginPaint()会发送一个WM_ERASEBKGND。
2.调用GetDC()和GetWindowDC(),获得的HDC,绘制范围是整个窗口。且在ReleaseDC()后,不会设置窗口的无效区域为有效(确切地说这种方式获得的dc,整个窗口都可以绘制,其无效区域是整个窗口)。可以在任意地方获取这个dc并绘图。
一个常见的疑惑是,在窗口重绘时,先发WM_PAINT还是先发WM_ERASEBKGND消息?答案是都有可能。
1.由于移动窗口,改变窗口,最大最小化窗口,导致的重绘。系统会先发WM_ERASEBKGND消息,后发WM_PAINT消息(此时OnPaint函数的wparam是一个hdc)。
2.由于调用了Invalidate()或InvalidateRect()导致的重绘。系统会发WM_PAINT消息。在处理WM_PAINT消息,通常会调用BeginPaint()(此时wparam是NULL)获得HDC。BeginPaint()会根据需要,决定是否发送WM_ERASEBKGND。
在看几个应用中的问题。
1.OnErasebkgnd()中,返回真表示已经擦除了背景,返回假表示没有擦除背景。这个返回值,只对BeginPaint()的第二个参数(这是一个传出型参数)PAINTSTRUCT的fErase有影响。OnErasebkgnd()返回假时,fErase被BeginPaint()设置为真,表示下面应该考虑擦除背景的事。
2.WTL中CPaintDC构造函数中会调用BeginPaint()获得dc,析构函数中会调用EndPaint()。
在做窗口界面优化的时候,正确的处理WM_PAINT和WM_ERASEBKGND是很重要的,不管是先产生WM_ERASEBKGND还是WM_PAINT.
在处理OnPaint时采用如下方法:
PAINTSTRUCT PS;
HDC hdc = BeginPaint(&PS);
做相关GDI操作
EndPaint(&PS);
处理OnEraseBkgnd时采用如下方法:
return 1;
第一种情况(WM_PAINT消息产生在前,WM_ERASEBKGND消息产生在后)
BeginPaint会检测是否删除背景,如果是,发送WM_ERASEBKGND(当WM_PAINT手动(由InvalidateRect等函数)产生时)
第二种情况(WM_PAINT消息产生在后,WM_ERASEBKGND消息产生在前)
在处理WM_PAINT之前已经处理了WM_ERASEBKGND
如果处理WM_ERASEBKGND消息时返回FALSE,BeginPaint标记pt.fErase 为TRUE,如果处理WM_ERASEBKGND时返回TRUE,BeginPaint标记pt.fErase为FALSE.WM_ERASEBKGND返回TRUE和返回FALSE是一个规范,一般情况下没有什么区别,但是如果什么时候用到了,会根据函数返回值判断后续处理。因此最好按照要求返回数据.
相关文章推荐
- WM_PAINT 和 WM_ERASEBKGND 消息的区别 .
- WM_PAINT 和 WM_ERASEBKGND 消息的区别
- Invalidate(TRUE)与Invalidate(FALSE)区别(前者会发送WM_ERASEBKGND消息全部刷新,然后使用WM_PAINT消息绘制,而后者只发送WM_PAINT消息)
- 窗口绘制有关的消息整理 WM_PAINT, WM_NCPAINT, WM_ERASEBKGND
- PAINT和WM_ERASEBKGND消息
- 深度分析WM_PAINT和WM_ERASEBKGND消息
- WM_PAINT和WM_ERASEBKGND消息
- 深度分析WM_PAINT和WM_ERASEBKGND消息
- MFC与SDK中的重画问题 。。WM_PAINT消息的处理
- GetMessage和PeekMessage的区别及PostMessage(hWnd, WM_QUIT, 0, 0)消息
- VC对话框如何添加WM_ERASEBKGND消息(OnEraseBkgnd函数)
- =WM_VSCROLL(消息反射) 和 WM_VSCROLL(消息响应)的区别(控件拥有者自己不处这个理消息,而是反射给控件对象本身来处理这个消息)
- WM_Paint 消息详解
- WM_PAINT与WM_ERASEBKGND
- 系统何时发送WM_PAINT消息
- 产生WM_PAINT 消息
- WM_ERASEBKGND消息及位图背景与透明的实现
- VC对话框如何添加WM_ERASEBKGND消息(OnEraseBkgnd函数)
- WM_PAINT和WM_ERASEBKGND
- WM_PAINT与WM_ERASEBKGND