老师们,请问一上多次擦出背景的原因
老师们,请教一下多次擦出背景的原因。
老师们,在问这些问题之前,其实看了不少资料,可能这些东西都是微软不开源的,问一些朋友,
他们也不是很清楚。
1. wm_erasebkgnd这个消息很多时候在wm_paint之前。
也就是说,很多时候,先依赖defwindowproc这个函数擦出背景(假设程序员没有重写wm_erasebkgnd)
,然后进入wm_paint.
此时用beginpaint------------endpaint这组函数。
这组函数2个功能:
(1)区域有效;(2)擦出背景
亮点:(2)擦出背景。 如果区域有效了,那么defwindorproc就不会擦出背景。除非无效,defwindproc?
问题:这难道是多次擦出背景嘛?
2. 手工invalidaterect(NULL,NULL,TRUE); 这个函数会投递一个 wm_paint. 注意最后一个参数,是会导致
wm_erasebkgnd产生的。会擦出背景。
这里的擦出背景,是wm_paint擦出 的,还是wm_erasebkgnd擦出的?
有时候wm_erasebkgnd会在wm_paint之后产生。
------最佳解决方案--------------------
本帖最后由 VisualEleven 于 2012-12-09 21:02:37 编辑 当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.
在窗口重绘时,对于是先发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.先是:wm_paint
2.然后wm_paint中的beginpaint 调 erasebkgnd
------其他解决方案--------------------
顶起来
别要沉了
------其他解决方案--------------------
该回复于2012-12-09 15:38:01被管理员删除
------其他解决方案--------------------
老师你好,
我认真看了你的答案。 你的2个答案几乎:wm_erasebkgnd在后。
这个恐怕有争议。
我做过实验,wm_erasebkgnd是在前的。
我们可以随便做个实验,采用vs2008简历一个win32工程。 新建后,添加wm_erasebkgnd即可。
然后设置断点。
如果其他朋友看到这个帖子,也可以做做实验,是否 这个结论与机子有关系
------其他解决方案--------------------
我感觉beginpaint说错了,这个函数不一定会擦出背景的。
其会使 无效区域变为有效。同时检测 berase的值。
如果发个窗口客户区提供了一个刷子,注意是从wndclass里提供的,
且berase为false, 那么此时 就算处理wm_paint 你返回return 0;
它也会擦出背景。
这个擦出背景 的动作不是在wm_erasebkgnd里处理 的。
是wm_paint完成的。
结论:客户区域的背景的擦出可以在多个消息里完成的。
老师们,在问这些问题之前,其实看了不少资料,可能这些东西都是微软不开源的,问一些朋友,
他们也不是很清楚。
1. wm_erasebkgnd这个消息很多时候在wm_paint之前。
也就是说,很多时候,先依赖defwindowproc这个函数擦出背景(假设程序员没有重写wm_erasebkgnd)
,然后进入wm_paint.
此时用beginpaint------------endpaint这组函数。
这组函数2个功能:
(1)区域有效;(2)擦出背景
亮点:(2)擦出背景。 如果区域有效了,那么defwindorproc就不会擦出背景。除非无效,defwindproc?
问题:这难道是多次擦出背景嘛?
2. 手工invalidaterect(NULL,NULL,TRUE); 这个函数会投递一个 wm_paint. 注意最后一个参数,是会导致
wm_erasebkgnd产生的。会擦出背景。
这里的擦出背景,是wm_paint擦出 的,还是wm_erasebkgnd擦出的?
有时候wm_erasebkgnd会在wm_paint之后产生。
------最佳解决方案--------------------
本帖最后由 VisualEleven 于 2012-12-09 21:02:37 编辑 当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.
在窗口重绘时,对于是先发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.先是:wm_paint
2.然后wm_paint中的beginpaint 调 erasebkgnd
------其他解决方案--------------------
顶起来
别要沉了
------其他解决方案--------------------
该回复于2012-12-09 15:38:01被管理员删除
------其他解决方案--------------------
老师你好,
我认真看了你的答案。 你的2个答案几乎:wm_erasebkgnd在后。
这个恐怕有争议。
我做过实验,wm_erasebkgnd是在前的。
我们可以随便做个实验,采用vs2008简历一个win32工程。 新建后,添加wm_erasebkgnd即可。
然后设置断点。
如果其他朋友看到这个帖子,也可以做做实验,是否 这个结论与机子有关系
------其他解决方案--------------------
我感觉beginpaint说错了,这个函数不一定会擦出背景的。
其会使 无效区域变为有效。同时检测 berase的值。
如果发个窗口客户区提供了一个刷子,注意是从wndclass里提供的,
且berase为false, 那么此时 就算处理wm_paint 你返回return 0;
它也会擦出背景。
这个擦出背景 的动作不是在wm_erasebkgnd里处理 的。
是wm_paint完成的。
结论:客户区域的背景的擦出可以在多个消息里完成的。