介绍:
我决定在 MS Visual Studio 2008 中制作一个测试项目,在 C++ 中测试纯 WIN32 中的小程序,将位图绘制为窗口背景。
问题:
窗口应该有灰色画笔和一张在其客户区域上拉伸的位图。
在我的代码中WM_PAINT
,如果我尝试在没有位图的情况下为窗口绘制灰色画笔,一切似乎都运行良好。
如果我只是尝试将位图作为背景,也是如此。
然而,当我将这两者结合起来时,我可以得到一张位图图片被拉伸,位图后面的灰色背景,这就是发生的事情:
位图图片看起来“静止”,但灰色画笔出现在整个窗口上一秒钟,然后完全消失,因此只看到拉伸的位图,然后再次出现,依此类推。
它似乎是从上到下绘制的,似乎应用程序又在做一遍。
这就是我在启动程序时看到的方式。
相关信息:
该程序是通过选择选项 File->New,然后从选项中选择 Win32 项目来制作的。
窗口类是自动设置的,下面的成员是这样设置的:
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
我添加了静态全局变量来存储位图句柄:
static HBITMAP bmp;
在向导创建的窗口过程中,我使用以下代码对其进行了初始化:
case WM_CREATE:
bmp = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1) );
return 0;
break;
在向导创建的窗口过程中,我添加了WM_PAINT
处理程序,代码如下:
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;
当调整窗口大小或擦除背景时,我也使客户区无效,如下所示:
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;
重要的提示:
即使我注释掉 and 的处理程序WM_SIZE
,WM_ERASEBKGND
效果仍然会发生。
我对双缓冲没有太多经验,但这很简单。
我只是看不到错误,所以我请更有经验和技能的同事帮忙。
如果需要额外的源代码,请索取它,我会发布它,但在那之前我会省略它以保持问题简短。