2017-03-14 38 views
-1

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

这是我的初始化函数

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(< - 链接没有打开新的选项卡,以便右点击并打开新标签,如果你想看到输出,它实际上只是一个错误信息...)

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

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

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

您可以使用调试器并在发生故障的MessageBox上放置断点,以便您可以看到myFile的值吗? – Neil

+0

其中'file'定义了什么,它的值 – sp2danny

+0

会更有用,如果你在'LoadImage'失败后显示'GetLastError',myFile'字符串 – RbMm

回答

0

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

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

从手册:

OFN_ALLOWMULTISELECT

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

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

nFileOffset成员是第一个文件名的偏移量(以字节或字节计),并且不使用nFileExtension成员。

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

当您发送到

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

你基本上要加载一个目录为位图。相反,你需要为每个选择单独创建名字,并分别载入这些名字。

+0

感谢您的及时回复。事情是,我需要OFN_ALLOWMULTISELECT,因为我希望用户能够加载多个图像。我怎样才能为每个选择创建单独的文件名?我的WinAPI知识并不那么先进,我只想实现这个基本功能,以便我可以为应用程序做其他事情。这个想法是让一个应用程序使用多线程并发地加载.bmp文件。 – Jason

+0

'strcat'会成为一个选项 –

+0

请问您能给我举个例子吗?我真的不知道如何或在哪里把:( – Jason