无法加载多个位图 - WinAPI

时间:2017-03-14 12:07:48

标签: c++ winapi bitmap

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

这是我的初始化功能

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)\0*.bmp\0\0");
    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:

输出1(&lt; - 链接无法打开新标签,因此如果要查看输出,请右键单击并打开新标签,它实际上只是一条错误消息... )

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

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

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

1 个答案:

答案 0 :(得分:0)

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

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

从手册:

  

<强> OFN_ALLOWMULTISELECT

     

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

     

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

     

nFileOffset成员是到的字节或字符的偏移量   第一个文件名,不使用nFileExtension成员。

     

目录和文件名字符串是NULL分隔的,带有额外的   最后一个文件名后面的空字符。

当您将其发送到

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

您实际上是在尝试将目录加载为位图。相反,您需要为每个选择单独创建精美名称,并分别加载它们。