2017-03-14 66 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