2017-03-14 12 views
-1

So kürzlich konnte ich meine Anwendung erhalten, um dem Benutzer zu ermöglichen, BMP-Dateien aus externen Verzeichnissen zu laden. Die Anwendung lädt das Bild gut, aber wenn der Benutzer mehrere Bilder hervorhebt, beschwert sich meine LoadImage() Funktion und ich denke, es liegt daran, dass es mehrere Dateien gleichzeitig bekommt, so dass es nicht weiß, wie man sie richtig liest. (könnte sein).Mehrere Bitmaps können nicht geladen werden - WinAPI

Hier ist meine Init Funktion

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; 
} 

Und hier ist, wie ich Bitmaps bin Laden und ruft Dinge:

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: 

Der Ausgang 1 (< - Einen Link nicht öffnet neuen Tab so rechts- Klicken Sie auf und öffnen Sie eine neue Registerkarte, wenn Sie die Ausgabe sehen möchten, es ist wirklich nur eine Fehlermeldung ...)

Vielen Dank für das Lesen meiner Abfrage. Ich würde sehr schätzen jede mögliche Hilfe, die Sie mir geben konnten :) tschüss.

EDIT: Hier sind einige Variablen-Definitionen:

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

Können Sie einen Debugger verwenden und einen Breakpoint auf die MessageBox setzen, die fehlschlägt, damit Sie den Wert von myFile sehen können? – Neil

+0

wo ist 'file' definiert, und was ist der Wert – sp2danny

+0

wird viel nützlicher sein, wenn Sie zeigen' GetLastError 'nach' LoadImage' fail mit 'myFile' string – RbMm

Antwort

0

Mein erster Vorschlag OFN_ALLOWMULTISELECT von den Fahnen zu entfernen wäre.

Wenn Sie es behalten, müssen Sie den Fall des Benutzers behandeln, der mehrere Dateien richtig auswählt.

Aus dem Handbuch:

OFN_ALLOWMULTISELECT

Der Dateiname Listenfeld ermöglicht eine Mehrfachauswahl. Wenn der Benutzer mehr als eine Datei auswählt, gibt der lpstrFile-Puffer den Pfad zum aktuellen Verzeichnis gefolgt von den Dateinamen der ausgewählten Dateien zurück.

Der Member nFileOffset ist der Offset in Byte oder Zeichen für den ersten Dateinamen , und das Member nFileExtension wird nicht verwendet.

Die Verzeichnis- und Dateinamenszeichenfolgen sind NULL-getrennt, mit einem zusätzlichen NULL-Zeichen nach dem letzten Dateinamen.

Wenn Sie senden, dass auf

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

Sie im Wesentlichen ein Verzeichnis als Bitmap zu laden versuchen. Stattdessen müssen Sie Fine-Namen für jede Auswahl einzeln erstellen und diese separat laden.

+0

Vielen Dank für Ihre schnelle Antwort. Das ist, ich brauche die OFN_ALLOWMULTISELECT, weil ich möchte, dass der Benutzer mehrere Bilder laden kann. Wie kann ich einzelne Dateinamen für jede Auswahl erstellen? Mein WinAPI-Wissen ist nicht so fortgeschritten, ich möchte nur diese grundlegende Funktionalität erreichen, damit ich etwas anderes für die Anwendung tun kann. Die Idee besteht darin, eine Anwendung zu erstellen, die .bmp-Dateien gleichzeitig mit Multi-Threading lädt. – Jason

+0

'strcat' wäre eine Option –

+0

Können Sie mir vielleicht ein Beispiel geben, wenn es nicht zu viel Mühe bitte ist? Ich weiß wirklich nicht, wie oder wo ich das hinstellen soll :( – Jason

Verwandte Themen