BeginPaint() 不擦除背景
BeginPaint() not erasing the background
BeginPaint() 文档说:
If the window's class has a background brush, BeginPaint uses that
brush to erase the background of the update region before returning.
我是这样设置画笔的:
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
我在 Window 上绘制了位图,然后使用以下代码要求重绘:
RedrawWindow(hWnd, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);
我在 WM_PAINT
中有此代码:
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
所以我预计 BeginPaint()
会擦除位图,但位图仍保留在 Window!
我正在使用 Windows 7.
(写这个作为答案,因为解释太长,无法评论)。
客户区的绘制可以在标准 Windows 模型中的两个位置完成:
WM_ERASEBKGND
名义上处理擦除背景。
WM_PAINT
名义上处理在背景上绘制东西。
如果将 WM_ERASEBKGND
传递给 DefWindowProc
,它将使用 class 画笔绘制背景。如果您想自己处理 WM_ERASEBKGND
,您有两种选择:
- 您可以自己擦除背景,并且return 1(或任何非零值)
- 可以不擦除,return0
如果您实施后一个选项,当您稍后收到 WM_PAINT
消息并调用 BeginPaint
时,PAINTSTRUCT
的 fErase
标志将设置为 TRUE
,说明背景还是被标记为擦除。
BeginPaint
函数本身根本不做任何绘画,它所做的只是给你一个可以绘画的DC
。当您调用 EndPaint
时,之前标记为脏的区域 "deemed" 已被绘制(并擦除)并且将不再被标记为脏。
背景擦除和前景绘画中的绘画划分(至少在我看来)是 16 位世界的残余,其中绘画是一项昂贵的操作。如果前景绘画也擦除背景(例如,您正在绘制纯色块或纯色图像),那么将背景作为单独的步骤擦除是浪费时间,并且通常会导致可见的闪烁。因此,根据您的应用程序,您可能希望完全忽略 "erase background" 步骤 - return 0
来自 WM_ERASEBKGND
并在 WM_PAINT
中绘制 "background and foreground"一步。
BeginPaint() 文档说:
If the window's class has a background brush, BeginPaint uses that brush to erase the background of the update region before returning.
我是这样设置画笔的:
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
我在 Window 上绘制了位图,然后使用以下代码要求重绘:
RedrawWindow(hWnd, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);
我在 WM_PAINT
中有此代码:
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
所以我预计 BeginPaint()
会擦除位图,但位图仍保留在 Window!
我正在使用 Windows 7.
(写这个作为答案,因为解释太长,无法评论)。
客户区的绘制可以在标准 Windows 模型中的两个位置完成:
WM_ERASEBKGND
名义上处理擦除背景。
WM_PAINT
名义上处理在背景上绘制东西。
如果将 WM_ERASEBKGND
传递给 DefWindowProc
,它将使用 class 画笔绘制背景。如果您想自己处理 WM_ERASEBKGND
,您有两种选择:
- 您可以自己擦除背景,并且return 1(或任何非零值)
- 可以不擦除,return0
如果您实施后一个选项,当您稍后收到 WM_PAINT
消息并调用 BeginPaint
时,PAINTSTRUCT
的 fErase
标志将设置为 TRUE
,说明背景还是被标记为擦除。
BeginPaint
函数本身根本不做任何绘画,它所做的只是给你一个可以绘画的DC
。当您调用 EndPaint
时,之前标记为脏的区域 "deemed" 已被绘制(并擦除)并且将不再被标记为脏。
背景擦除和前景绘画中的绘画划分(至少在我看来)是 16 位世界的残余,其中绘画是一项昂贵的操作。如果前景绘画也擦除背景(例如,您正在绘制纯色块或纯色图像),那么将背景作为单独的步骤擦除是浪费时间,并且通常会导致可见的闪烁。因此,根据您的应用程序,您可能希望完全忽略 "erase background" 步骤 - return 0
来自 WM_ERASEBKGND
并在 WM_PAINT
中绘制 "background and foreground"一步。