Winapi 抑制WM_擦除BKGND的正确方法是什么?

Winapi 抑制WM_擦除BKGND的正确方法是什么?,winapi,doublebuffered,Winapi,Doublebuffered,如果我需要使用双缓冲,我需要抑制WM_ERASEBKGND消息 我可以处理WM_ERASEBKGND并立即返回。但是我可以将WNDCLASS/WNDCLASSEX的hbrBackground设置为NULL而不处理WM_ERASEBKGND消息吗?这是正确的方法吗?是的,将hbrBackground设置为NULL是避免实现无操作WM_ERASEBKGND处理程序的适当方法 将WM_ERASEBKGND传递到DefWindowProc时,它会检查窗口类中的背景笔刷。如果有,它将用它填充脏区域。如果背

如果我需要使用双缓冲,我需要抑制
WM_ERASEBKGND
消息


我可以处理
WM_ERASEBKGND
并立即返回。但是我可以将
WNDCLASS
/
WNDCLASSEX
hbrBackground
设置为
NULL
而不处理
WM_ERASEBKGND
消息吗?这是正确的方法吗?

是的,将
hbrBackground
设置为
NULL
是避免实现无操作
WM_ERASEBKGND
处理程序的适当方法

WM_ERASEBKGND
传递到
DefWindowProc
时,它会检查窗口类中的背景笔刷。如果有,它将用它填充脏区域。如果背景笔刷为null,则它不执行任何操作并返回。这与拥有自己的无所事事
WM_ERASEBKGND
处理程序基本相同


WM_-ERASEBKGND
处理程序的返回值影响
PAINTSTRUCT
调用
BeginPaint
时得到的
fErase
字段。
WM_PAINT
处理程序应该检查
fErase
,以确定是否需要擦除背景本身,或者是否已经由
WM_ERASEBKGND
完成。(尽管我从未见过有人检查过。)如果让
DefWindowProc
处理
WM_ERASEBKGND
如果它有颜色编号或画笔,它将返回
TRUE
,如果
hbrBackground
NULL
我认为设置
hbrBackground=GetStockObject(空心画笔)更正确
将其设置为
NULL

区分:

如果不希望自动绘制背景,请传递空心笔刷。如果需要自定义背景图形,则将
NULL
作为画笔传递

“的
hbrBackground
成员说:

当此成员为
NULL
时,每当请求应用程序在其客户端区域中绘制时,应用程序必须绘制自己的背景。为了确定是否必须绘制背景,应用程序可以处理
WM_ERASEBKGND
消息,或者测试
PAINTSTRUCT
函数填充的
PAINTSTRUCT
结构的
fErase
成员

报告说:

DefWindowProc
函数使用
WNDCLASS
结构的
hbrBackground
成员指定的类背景画笔擦除背景。如果
hbrBackground
NULL
,应用程序应处理
WM_ERASEBKGND
消息并擦除背景


我的解释是,将
hbrBackground
设置为
NULL
,然后忽略处理
WM_ERASEBKGND
并不意味着严格合法(但可能有效)
hbrBackground=NULL
承诺您将自己处理
WM_ERASEBKGND
并且不会让
DefWindowProc
尝试使用NULL指针进行绘制。

请注意,您仍然会收到
WM_ERASEBKGND
的邮件。唯一的区别是,如果你不处理它,什么也不会发生(可以安全地忽略)。你确定这是一种犹太方法吗?你知道为什么要用空刷子吗?是的,这是洁食。对于
hbrBackground
,MSDN说,“当这个成员为NULL时,应用程序必须在其客户端区域中绘制自己的背景。”@AdrianMcCarthy我的意思是:你确定将
hbrBackground
设置为
NULL
并且不处理
WM_ERASEBKGND
(原始问题)是否符合犹太教原则。您引用的MSDN文档确实说“应用程序必须绘制自己的背景…”。(不过,你的评论是有道理的。)“…只要它被要求在其客户区域内进行绘画。”这表明在WM_paint中进行绘画是可以的。WM_橡皮擦BKGND由BeginPaint调用发送(如果无效区域也被标记为擦除),因此它已经在WM_PAINT处理程序中发生。为了确保理论与实践相符,我刚刚对它进行了测试。如果hbrBackground为NULL,那么DefWindowProc对WM_ERASEBKGND的处理只会返回FALSE。我认为您分析得太多了。将hbrBackground设置为NULL是正确的。您可以通过处理WM_ERASEBKGND自己填充背景,也可以在WM_PAINT中填充背景。如果指定了画笔(或颜色)并填充了该区域,则WM_ERASEBKGND的DefWindowProc将返回TRUE。如果hbrBackground为NULL,则返回FALSE。没关系。我认为区别在于你从BeginPaint获得的PAINTSTRUCT的fErase成员发生了什么。如果选择了空心画笔,默认的WM_ERASEBKGND处理程序将填充空心画笔并返回TRUE(表示“我擦除了背景)。这会导致fErase成员为FALSE,因此WM_PAINT处理程序的其余部分不会被诱骗进行自己的擦除。如果为NULL,则默认的WM_ERASEBKGND处理程序不会执行任何操作,并返回FALSE(“我没有擦除背景”),这会导致fErase成员为TRUE。在PAINTSTRUCT的文档中,在fErase下,它会说:如果窗口类是在没有背景笔刷的情况下创建的,应用程序负责擦除背景。“因此,完全没有背景笔刷是合法的。在这里,”应用程序说指的是WM_PAINT处理程序,因为当您从BeginPaint获得PAINTSTRUCT时,WM_ERASEBKGND已经来了又走了。是的,您仍然负责绘制背景,但是WM_绘制处理程序是一个合法的地方。