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

标签 c++ winapi bitmap

我试图在启动应用程序时加载一些位图。我试图在 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 返回整个窗口的 dc,包括非客户区。您通常需要 GetDC 来代替。

  2. 在响应 WM_PAINT 并返回 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;

关于C++ Win32 在 WM_CREATE 中加载多个位图不会加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57945118/

相关文章:

c - 想知道如何通过 win32 应用程序中的程序在文件上写入任何内容

C# 用阴影给图像着色

android - app 和 uri 的内部存储

C++ istream 运算符重载 - 即使声明为 friend 也无法访问数据成员

c++ - 模板有问题。错误 : Cannot deduce template argument for type 'T'

c++ - 如何为共享基类并在定义结构之后定义的结构定义复制构造函数

c++ - 在 C++ 中编辑位图

c++ - 嵌套结构和在 C++ 中访问数据

c++ - 如何使用 cl.exe 静态链接库以使用 SHGetSpecialFolderPath

windows - 如何确定哪些任务栏应用程序/窗口正在请求用户注意