C++ Win32 在 WM_CREATE 中加载多个位图不会加载

C++ Win32 loading multiple bitmaps in WM_CREATE won't load

我正在尝试在启动应用程序时加载一些位图。我试图在 WM_CREATE 中加载它们,但只有我加载的最后一个位图会保持加载状态。

我可以在 WM_PAINT 中加载图片,但有人告诉我最好在 WM_CREATE 中加载它们。

//before switch statement
static HBITMAP bitmap1, bitmap2;

case WM_CREATE: {
    HINSTANCE hInstance = GetModuleHandle(NULL);

    bitmap1 = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP1),
            IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);

    bitmap2 = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP2),
        IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);

    if (!bitmap1 || !bitmap2) MessageBox(NULL, _T("Error while loading images"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK);

case WM_PAINT:{
    //Draw bitmap...
}

我希望两个位图都像在内部加载时一样加载 WM_PAINT

编辑:

问题出乎我的意料。问题是它绘制在我制作的填充区域后面。我还是不知道怎么解决。

//Draw bitmap function
bool DrawBitmap(HBITMAP hBitmap, int posX, int posY, int sizeX, int sizeY)
{
    BITMAP bmp;

    HWND hWnd = FindWindow(windowClassName, NULL);
    if (!hWnd) return false;

    HDC hdc = GetDC(hWnd);
    if (!hdc) return false;

    HDC hBitmapDC = CreateCompatibleDC(hdc);
    if (!hBitmapDC) return false;

    GetObject(hBitmap, sizeof(bmp), &bmp);

    SelectObject(hBitmapDC, hBitmap);
    BitBlt(hdc, posX, posY, sizeX, sizeY, hBitmapDC, 0, 0, SRCCOPY);

    DeleteObject(hBitmap);
    ReleaseDC(hWnd, hBitmapDC);
    ReleaseDC(hWnd, hdc);
    return true;
}

//Before switch
RECT recRect;
STATIC HBITMAP bitmap1;

//case WM_CREATE:
case WM_CREATE: {
    HINSTANCE hInstance = GetModuleHandle(NULL);

    bitmap1 = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP1),
            IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
    if (!bitmap) MessageBox(NULL, _T("Error while loading images"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK);
    return 0;
    break;

//case WM_PAINT
case WM_PAINT:
    DefWindowProc(hwnd, msg, wParam, lParam);

    hdc = GetWindowDC(hwnd);
    recRect = { -1, -1, 50 + 1, 30 + 1 };
    FillRect(hdc, &recRect, (HBRUSH)CreateSolidBrush(RGB(30, 30, 30)));


    if (DrawBitmap(bitmap1, 5, 5, 10, 10) == false) MessageBox(NULL, _T("Error while drawing images"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK);
        return DefWindowProc(hwnd, msg, wParam, lParam);
    return 0;
    break;

WM_PAINT

中声明位图时没有出现问题
  1. GetWindowDC return整个window的dc,包括非客户区。您通常需要 GetDC 来代替。

  2. 在回复 WM_PAINT 和 return 0 时始终使用 BeginPaint/EndPaint

  3. CreateSolidBrush 是 GDI 资源泄漏。创建画笔或其他 GDI 对象后,必须销毁这些对象,否则会发生资源泄漏,程序将在 10,000 次 GDI 泄漏后崩溃。

  4. 在你的绘制函数中你有DeleteObject(hBitmap)这将立即销毁位图。但是您可能希望保留位图句柄并仅在程序完成后销毁它。

建议:

bool DrawBitmap(HDC hdc, HBITMAP hBitmap, int posX, int posY, int sizeX, int sizeY)
{
    HDC memdc = CreateCompatibleDC(hdc);
    HGDIOBJ oldbmp = SelectObject(memdc, hBitmap);
    BitBlt(hdc, posX, posY, sizeX, sizeY, memdc, 0, 0, SRCCOPY);
    SelectObject(memdc, oldbmp);
    DeleteDC(memdc);
    return true;
}

...
case WM_PAINT:
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);

    HBRUSH hbrush = CreateSolidBrush(RGB(255, 0, 0));
    FillRect(hdc, &ps.rcPaint, hbrush);
    DeleteObject(hbrush); 

    BITMAP bm1;
    GetObject(bitmap1, sizeof(bm1), &bm1);
    DrawBitmap(hdc, bitmap1, 0, 0, bm1.bmWidth, bm1.bmHeight);

    int x = bm1.bmWidth;
    int y = bm1.bmHeight;
    BITMAP bm2;
    GetObject(bitmap2, sizeof(bm2), &bm2);
    DrawBitmap(hdc, bitmap2, x, y, bm2.bmWidth, bm2.bmHeight);

    EndPaint(hwnd, &ps);
    return 0;
}

case WM_DESTROY:
    DeleteObject(bitmap1);
    DeleteObject(bitmap2);
    PostQuitMessage(0);
    return 0;