无法加载多个位图 - Winapi

Unable to load multiple bitmaps - WinAPI

本文关键字:位图 Winapi 加载      更新时间:2023-10-16

所以最近我能够获取我的应用程序,以允许用户从外部目录加载.bmp文件。该应用程序可以加载图片,但是如果用户突出显示多个图片,我的LoadImage()函数会抱怨,我认为这是因为它一次获取多个文件,因此它不知道如何正确读取它们。(或许)。

这是我的init功能

void InitialiseDialog(HWND hwnd)
{
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hInstance = GetModuleHandle(NULL);
    ofn.lpstrCustomFilter = NULL;
    ofn.nMaxCustFilter = 0;
    ofn.nFilterIndex = 0;
    ofn.nMaxFile = MAX_PATH;
    ofn.hwndOwner = hwnd;
    ofn.lpstrFile = file;
    ofn.lpstrFilter = TEXT("Bitmap Files (*.bmp)*.bmp");
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = MAX_PATH;
    ofn.lpstrInitialDir = NULL;
    ofn.lpstrTitle = NULL;
    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT;
    ofn.nFileOffset = 0;
    ofn.nFileExtension = 0;
    ofn.lpstrDefExt = NULL;
    ofn.lCustData = 0L;
    ofn.lpfnHook = NULL;
    ofn.lpTemplateName = NULL;
}

这是我加载位图并调用事物的方式:

bool LoadAndBlitBitmap(LPCWSTR myFile, HDC hWinDC)
{
    // Load the bitmap image file
    hBitmap = (HBITMAP)::LoadImage(NULL, myFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    // Verify that the image was loaded
    if (hBitmap == NULL) {
        ::MessageBox(NULL, L"LoadImage Failed", L"Error", MB_OK);
        return false;
    }
    // Create a device context that is compatible with the window
    HDC hLocalDC;
    hLocalDC = ::CreateCompatibleDC(hWinDC);
    // Verify that the device context was created
    if (hLocalDC == NULL) {
        ::MessageBox(NULL, L"CreateCompatibleDC Failed", L"Error", MB_OK);
        return false;
    }
    // Get the bitmap's parameters and verify the get
    BITMAP qBitmap;
    int iReturn = GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP),
        reinterpret_cast<LPVOID>(&qBitmap));
    if (!iReturn) {
        ::MessageBox(NULL, L"GetObject Failed", L"Error", MB_OK);
        return false;
    }
    // Select the loaded bitmap into the device context
    HBITMAP hOldBmp = (HBITMAP)::SelectObject(hLocalDC, hBitmap);
    if (hOldBmp == NULL) {
        ::MessageBox(NULL, L"SelectObject Failed", L"Error", MB_OK);
        return false;
    }
    // Blit the dc which holds the bitmap onto the window's dc
    BOOL qRetBlit = ::BitBlt(hWinDC, 0, 0, qBitmap.bmWidth, qBitmap.bmHeight,
        hLocalDC, 0, 0, SRCCOPY);
    if (!qRetBlit) {
        ::MessageBox(NULL, L"Blit Failed", L"Error", MB_OK);
        return false;
    }
    // Unitialize and deallocate resources
    ::SelectObject(hLocalDC, hOldBmp);
    ::DeleteDC(hLocalDC);
    ::DeleteObject(hBitmap);
    return true;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    switch (message)
    {
    case WM_CREATE:
        InitialiseDialog(hWnd);
        return 0;
    case WM_COMMAND:
        wmId = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case ID_FILE_LOADIMAGES:
            if (GetOpenFileName(&ofn))
            {
                g_bhBitmap = !g_bhBitmap;
            }
            InvalidateRect(hWnd, NULL, TRUE);
            return 0;
            break;
        case ID_FILE_LOADAUDIO:
            DestroyWindow(hWnd);
            break;
        case ID_FILE_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        if (g_bhBitmap)
        {
            LoadAndBlitBitmap(file, hdc); // <-- Something not right about this...? 
        }
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:

output1(&lt; - link不会打开新标签,因此右键单击并打开新选项卡如果您想查看输出,这实际上只是一个错误消息...)

感谢您阅读我的查询。我非常感谢您可以给我的任何帮助:)再见。

编辑:以下是一些变量定义:

// Global Variables
HINSTANCE g_hInst;
HBITMAP hBitmap;
HDC hdc;
static OPENFILENAME ofn;
bool g_bhBitmap = false;
wchar_t file[1024];

我的第一个建议是从标志中删除 OFN_ALLOWMULTISELECT

如果保留它,则需要处理用户正确选择多个文件的情况。

手册:

ofn_allowmultiselect

文件名列表框允许多个选择。

如果用户选择多个文件,则LPSTRFILE缓冲区返回 通往当前目录的路径,然后是文件名 选定的文件。

nfileOffset成员是字节或字符的偏移 第一个文件名和不使用NFileExtension成员。

目录和文件名字符串是无效的,有一个额外的 最后一个文件名之后的null字符。

当您将其发送到

hBitmap = (HBITMAP)::LoadImage(NULL, myFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

您实际上是在尝试将目录作为位图加载。相反,您需要单独为每个选择创建命名命名,然后分离加载。