INTRODUCTION:
I have decided to make a test project in MS Visual Studio 2008, in C++ to test a small program in pure WIN32, regarding painting a bitmap as window's background.
PROBLEM:
Window should have gray brush and a bitmap picture stretched over its client area.
In my code for WM_PAINT, if I try to paint gray brush for window, without bitmap, everything seems to work well.
Same goes if I just try to put a bitmap as a background.
Yet, when I combine these two, so I can get a bitmap picture stretched, and gray background behind bitmap, this is what happens:
Bitmap picture appears to "stands still", but gray brush appears over entire window for a second, then disappears entirely, so only stretched bitmap is seen, and then appears again, and so on.
It seems as if it is drawn from top going to the bottom, and it seems as if application is doing it all over again.
This is how I see it when I start my program.
RELEVANT INFORMATION:
The program was made by choosing option File->New, and then choosing Win32 project from the options.
Window class was set automatically, and the following members were set like this:
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
I have added static global variable to store bitmap handle:
static HBITMAP bmp;
In the window procedure, made by the wizard, I have initialized it with following code:
case WM_CREATE:
bmp = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1) );
return 0;
break;
In the window procedure, made by the wizard, I have added WM_PAINT handler, with following code:
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;
I have also invalidated client area when window is resized, or erasing of background happens, like this:
case WM_ERASEBKGND:
InvalidateRect( hWnd, NULL, TRUE );
return 1L;
break;
case WM_SIZE:
InvalidateRect( hWnd, NULL, TRUE );
return 0L;
Bitmap is destroyed like this:
case WM_DESTROY:
DeleteObject( bmp );
PostQuitMessage(0);
break;
IMPORTANT NOTE:
Even if I comment out handlers for WM_SIZE and WM_ERASEBKGND, the effect still occurs.
I do not have much experience with double buffering, but this is simple thing to do.
I just fail to see the mistake, so I ask more experienced and skillfull colleagues to help.
If additional source code is required, ask for it and I will post it, but until then I will omit it to keep the question brief.
InvalidateRectinWM_ERASEBKGND. Your job there is to erase the background. - David Heffernan