GDI+ Graphics::DrawImage 不工作

GDI+ Graphics::DrawImage doesn't work

我正在尝试使用 GDI+ 绘制图像。当我在 WM_PAINT 中执行时,它起作用了:

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;

}

但是当我点击按钮或在 WM_CREATE 内部执行此操作时,它不会绘制图像:

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

即使我使用 BeginPaint()EndPaint() 它仍然失败。那么,有没有办法在WM_PAINT之外绘制图像?

在 Win32 中,几乎所有绘图都必须在 WM_PAINT 处理程序中进行。 可能您没有看到任何绘图,因为一旦您完成处理按钮点击,您就会收到 WM_PAINT.

如果你在外面画画 WM_PAINT 你的画会因为 windows 失效然后 WM_PAINT 消息而缩短寿命。

因此在 Win32 中绘制的正确方法是 WM_PAINT 处理程序。

我根据作者的评论编辑了答案。 假设您需要在单击鼠标后更改图像。你可以这样做:

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;
}

InvalidateRect 函数就是答案。使用该函数,您告诉 Windows 重绘 window。这是 link 手册页:InvalidateRect

如果您需要根据按钮点击(或与此相关的任何其他 Windows 事件处理程序)更新图像,您必须使图像在屏幕上占据的区域无效——通常通过 InvalidateRect()—然后让您的 WM_PAINT 处理程序绘制图像。