Reputation: 81
I'm working on a windows desktop application and I noticed to my dismay that my text was flickering so upon searching I found two methods - return true for erasebkgnd and double buffering. The first method didn't do anything and the second made my background all black for some reason and it still flickers.
Below is where I call paint and the buffering:
case WM_PAINT: {
PAINTSTRUCT ps;
HDC screen = BeginPaint(hWnd, &ps);
putImage(screen, hWnd);
RECT rc;
GetClientRect(hWnd, &rc);
HDC memdc;
auto hbuff = BeginBufferedPaint(screen, &rc, BPBF_COMPATIBLEBITMAP, NULL, &memdc);
EndBufferedPaint(hbuff, TRUE);
EndPaint(hWnd, &ps); } break;
and this next part is the putImage function
void putImage(HDC hdc, HWND hWnd)
{
Graphics graphic(hdc);
graphic.DrawImage(Image::FromFile(filePath), 10, 10);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
}
I was wondering what the problem was and if there is a fix for this.
Upvotes: 0
Views: 421
Reputation: 9700
my background all black
This issue is due to not filling the your background. You can fill your background before draw the image like this:
RECT rc;
GetClientRect(hWnd, &rc);
FillRect(screen, &rc, GetSysColorBrush(COLOR_WINDOW));
flickering
This issue is due to not using BeginBufferedPaint
in correct manner. Call BeginBufferedPaint
before drawing the image like this:
case WM_PAINT: {
PAINTSTRUCT ps;
HDC screen = BeginPaint(hWnd, &ps);
HPAINTBUFFER hbuff = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &screen);
if (hbuff)
{
RECT rc;
GetClientRect(hWnd, &rc);
FillRect(screen, &rc, GetSysColorBrush(COLOR_WINDOW));
putImage(screen, hWnd);
hr = EndBufferedPaint(hbuff, TRUE);
}
EndPaint(hWnd, &ps); } break;
And don't forget to call BufferedPaintInit
and BufferedPaintUnInit
. For example like this:
case WM_CREATE:
{
hr = BufferedPaintInit();
}
break;
//...
case WM_DESTROY:
{
BufferedPaintUnInit();
PostQuitMessage(0);
}
break;
Update: The complete code.
void putImage(HDC hdc, HWND hWnd)
{
Graphics graphic(hdc);
Image* image = Image::FromFile(L"path-to\\test.png");
Status status = graphic.DrawImage(image, 10, 10);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
DWORD err;
HRESULT hr;
static HDC memdc;
switch (message)
{
case WM_CREATE:
{
hr = BufferedPaintInit();
}
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC screen = BeginPaint(hWnd, &ps);
HPAINTBUFFER hbuff = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &screen);
if (hbuff)
{
RECT rc;
GetClientRect(hWnd, &rc);
FillRect(screen, &rc, GetSysColorBrush(COLOR_WINDOW));
putImage(screen, hWnd);
hr = EndBufferedPaint(hbuff, TRUE);
}
EndPaint(hWnd, &ps); } break;
case WM_DESTROY:
{
BufferedPaintUnInit();
PostQuitMessage(0);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Upvotes: 1