WM#U油漆处理器不';如果不能正常工作,就会出现闪烁效果 导言: 我决定在MS Visual Studio 2008中做一个测试项目,用C++来测试纯Win32中的一个小程序,把位图画成窗口的背景。 问题:
窗口应该有灰色的画笔和一个位图图片在其客户端区域上延伸 在我的WM#U油漆处理器不';如果不能正常工作,就会出现闪烁效果 导言: 我决定在MS Visual Studio 2008中做一个测试项目,用C++来测试纯Win32中的一个小程序,把位图画成窗口的背景。 问题:,c++,winapi,C++,Winapi,窗口应该有灰色的画笔和一个位图图片在其客户端区域上延伸 在我的WM_PAINT代码中,如果我尝试在没有位图的情况下为窗口绘制灰色画笔,那么一切看起来都很好 如果我只是尝试将位图作为背景,也是一样的 然而,当我将这两个组合起来时,我可以得到一张拉伸的位图图片,位图后面是灰色背景,这就是发生的情况: 位图图片显示为“静止”,但灰色画笔在整个窗口上出现一秒钟,然后完全消失,所以只看到拉伸的位图,然后再次出现,依此类推 它似乎是从上到下绘制的,并且似乎应用程序正在从头再来 这就是我在启动程序时的看法 相
WM_PAINT
代码中,如果我尝试在没有位图的情况下为窗口绘制灰色画笔,那么一切看起来都很好
如果我只是尝试将位图作为背景,也是一样的
然而,当我将这两个组合起来时,我可以得到一张拉伸的位图图片,位图后面是灰色背景,这就是发生的情况:
位图图片显示为“静止”,但灰色画笔在整个窗口上出现一秒钟,然后完全消失,所以只看到拉伸的位图,然后再次出现,依此类推
它似乎是从上到下绘制的,并且似乎应用程序正在从头再来
这就是我在启动程序时的看法
相关信息:
程序是通过选择选项文件->新建,然后从选项中选择Win32 project来完成的
窗口类是自动设置的,下面的成员是这样设置的:
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
case WM_ERASEBKGND:
InvalidateRect( hWnd, NULL, TRUE );
return 1L;
break;
case WM_SIZE:
InvalidateRect( hWnd, NULL, TRUE );
return 0L;
case WM_DESTROY:
DeleteObject( bmp );
PostQuitMessage(0);
break;
我添加了静态全局变量来存储位图句柄:
static HBITMAP bmp;
在向导创建的窗口过程中,我使用以下代码对其进行了初始化:
case WM_CREATE:
bmp = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1) );
return 0;
break;
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
RECT r;
GetClientRect( hWnd, &r );
// TODO: Add any drawing code here...
// fill client area with gray brush, just to test
FillRect( hdc, &r, (HBRUSH)GetStockObject( GRAY_BRUSH ) );
// memory DC for double buffering
HDC MemDC = CreateCompatibleDC( hdc );
// select our bitmap into memory DC
HBITMAP old = (HBITMAP)SelectObject( MemDC, bmp );
// get bitmap's width and height so we can stretch it
BITMAP b;
GetObject( bmp, sizeof(BITMAP), &b );
// stretch our bitmap
StretchBlt( hdc, 0, 0, r.right - r.left, r.bottom - r.top,
MemDC, 0, 0, b.bmWidth, b.bmHeight, SRCCOPY );
// perform proper cleanup
SelectObject( MemDC, old );
DeleteDC(MemDC);
EndPaint(hWnd, &ps);
}
return 0L;
break;
在向导创建的窗口过程中,我添加了WM_PAINT
handler,代码如下:
case WM_CREATE:
bmp = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1) );
return 0;
break;
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
RECT r;
GetClientRect( hWnd, &r );
// TODO: Add any drawing code here...
// fill client area with gray brush, just to test
FillRect( hdc, &r, (HBRUSH)GetStockObject( GRAY_BRUSH ) );
// memory DC for double buffering
HDC MemDC = CreateCompatibleDC( hdc );
// select our bitmap into memory DC
HBITMAP old = (HBITMAP)SelectObject( MemDC, bmp );
// get bitmap's width and height so we can stretch it
BITMAP b;
GetObject( bmp, sizeof(BITMAP), &b );
// stretch our bitmap
StretchBlt( hdc, 0, 0, r.right - r.left, r.bottom - r.top,
MemDC, 0, 0, b.bmWidth, b.bmHeight, SRCCOPY );
// perform proper cleanup
SelectObject( MemDC, old );
DeleteDC(MemDC);
EndPaint(hWnd, &ps);
}
return 0L;
break;
在调整窗口大小或清除背景时,我也会使客户端区域无效,如下所示:
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
case WM_ERASEBKGND:
InvalidateRect( hWnd, NULL, TRUE );
return 1L;
break;
case WM_SIZE:
InvalidateRect( hWnd, NULL, TRUE );
return 0L;
case WM_DESTROY:
DeleteObject( bmp );
PostQuitMessage(0);
break;
位图被销毁如下:
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
case WM_ERASEBKGND:
InvalidateRect( hWnd, NULL, TRUE );
return 1L;
break;
case WM_SIZE:
InvalidateRect( hWnd, NULL, TRUE );
return 0L;
case WM_DESTROY:
DeleteObject( bmp );
PostQuitMessage(0);
break;
重要提示:
即使我注释掉WM_SIZE
和WM_ERASEBKGND
的处理程序,效果仍然会出现
我没有太多的双缓冲经验,但这是一件简单的事情
我只是看不出错误,所以我请更有经验和技能的同事帮忙
如果需要额外的源代码,请索取它,我将发布它,但在此之前,我将省略它以保持问题的简短 您不应在
WM_ERASEBKGND
中调用invalidate
。这将迫使一系列无休止的绘画循环
WM_ERASEBKGND
的工作就是绘制背景,这就是你应该做的一切。如果您的WM_PAINT
要绘制整个窗口,则无需绘制任何背景。在这种情况下,我认为这是您的场景,您不应该在WM_ERASEBKGND
中执行任何操作您不应该在WM_ERASEBKGND
中调用invalidate
。这将迫使一系列无休止的绘画循环
WM_ERASEBKGND
的工作就是绘制背景,这就是你应该做的一切。如果您的WM_PAINT
要绘制整个窗口,则无需绘制任何背景。在这种情况下,我认为这是您的场景,您不应该在WM_-ERASEBKGND
中执行任何操作,不要在WM_-ERASEBKGND
中调用invalidate
。你在那里的工作就是抹去背景。它似乎是有效的,如果你确定这是问题所在,发表一个答案,我会接受并投赞成票。非常感谢。问候。不要在WM_ERASEBKGND
中调用invalidate
。你在那里的工作就是抹去背景。它似乎是有效的,如果你确定这是问题所在,发表一个答案,我会接受并投赞成票。非常感谢。谢谢你,海夫曼先生,谢谢你的帮助,我很感激。谢谢你,海夫曼先生,谢谢你的帮助,我很感激。当做