Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GDI+ Graphics::DrawImage doesn't work

Tags:

c++

gdi+

I am trying to draw an image using GDI+. When I do it inside WM_PAINT it works:

case WM_PAINT: {
    hdc = BeginPaint(hWnd, &ps);
    Gdiplus::Graphics graphics(hdc);
    Gdiplus::Image gdiImage(L"unt.png");
    graphics.DrawImage(&gdiImage, 40, 40);
    EndPaint(hWnd, &ps);

    break;

}

But when I do it on a button click or inside WM_CREATE it doesn't draw the image:

HDC hdc2 = GetDC(hWnd);
Gdiplus::Graphics graphics(hdc2);
Gdiplus::Image gdiImage(L"unt.png");
graphics.DrawImage(&gdiImage, 40, 40);

Even if I use BeginPaint() and EndPaint() it still fails. So, is there any way to draw the image outside of WM_PAINT?

like image 836
DimChtz Avatar asked Mar 18 '16 20:03

DimChtz


1 Answers

In Win32, almost all drawing must happen in WM_PAINT handler. Probably you don't see any drawing because as soon you finish to handle the button click, you receive a WM_PAINT.

If you draw outside WM_PAINT your drawing have short life because of invalidation of windows and then WM_PAINT message.

So the correct way to draw in Win32 is the WM_PAINT handler.

I edited the answer after a comment of author. Suppose you need to change the image after a mouse click. You can do:

case WM_PAINT: {
    hdc = BeginPaint(hWnd, &ps);
    Gdiplus::Graphics graphics(hdc);
    Gdiplus::Image gdiImage(clicked ? L"image_A.png" : L"image_B.png");
    graphics.DrawImage(&gdiImage, 40, 40);
    EndPaint(hWnd, &ps);
    break;

}
case WM_LBUTTONDOWN: {
    clicked = true;
    InvalidateRect(hwnd, NULL, true);
    break;
}

The InvalidateRect function is the answer. With that function you tell to Windows to redraw the window. This is the link to man page:InvalidateRect

like image 133
alangab Avatar answered Sep 17 '22 23:09

alangab