2017-03-14 1 views
-1

J'ai récemment pu obtenir mon application pour permettre à l'utilisateur de charger des fichiers .bmp à partir de répertoires externes. L'application charge l'image très bien, mais si l'utilisateur met en évidence plusieurs images, ma fonction LoadImage() se plaint et je pense que c'est parce qu'elle obtient plusieurs fichiers à la fois, donc elle ne sait pas comment les lire correctement. (peut être).Impossible de charger plusieurs bitmaps - WinAPI

Voilà ma fonction 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)\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; 
} 

Et voici comment je charger bitmaps et les choses Vocation:

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: 

La sortie 1 (< - Link ne pas ouvrir un nouvel onglet si droite cliquez et ouvrez un nouvel onglet si vous voulez voir la sortie, c'est vraiment juste un message d'erreur ...)

Merci d'avoir lu ma recherche. J'apprécierais grandement toute aide que vous pourriez me donner :) au revoir.

EDIT: Voici quelques définitions variables:

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

Pouvez-vous utiliser un débogueur et mettre un point d'arrêt sur le MessageBox qui échoue, de sorte que vous pouvez voir la valeur de myFile? – Neil

+0

où 'file' est défini, et quelle est sa valeur – sp2danny

+0

sera beaucoup plus utile si vous montrez' GetLastError' après que 'LoadImage' échoue avec la chaîne' myFile' – RbMm

Répondre

0

Ma première suggestion serait de supprimer OFN_ALLOWMULTISELECT des drapeaux.

Si vous le conservez, vous devez gérer la casse de l'utilisateur en sélectionnant plusieurs fichiers correctement.

A partir du manuel:

OFN_ALLOWMULTISELECT

La zone de liste Nom de fichier permet à plusieurs sélections.

Si l'utilisateur sélectionne plusieurs fichiers, le tampon lpstrFile renvoie le chemin d'accès au répertoire en cours suivi des noms de fichier des fichiers sélectionnés .

Le membre nFileOffset est le décalage, en octets ou en caractères, du premier nom de fichier et le membre nFileExtension n'est pas utilisé.

Les chaînes du répertoire et du nom de fichier sont séparées par une valeur NULL, avec un caractère supplémentaire après le dernier nom de fichier.

Lorsque vous envoyez à ce

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

vous essayez de charger essentiellement un répertoire en tant que bitmap. Au lieu de cela, vous devez créer individuellement des noms de fin pour chaque sélection et les charger séparément.

+0

Merci pour votre réponse rapide. La chose est, j'ai besoin de l'OFN_ALLOWMULTISELECT parce que je veux que l'utilisateur puisse charger plusieurs images. Comment puis-je créer des noms de fichiers individuels pour chaque sélection? Mes connaissances WinAPI ne sont pas si avancées, je veux juste atteindre cette fonctionnalité de base pour pouvoir faire autre chose à l'application. L'idée est de faire une application qui charge des fichiers .bmp simultanément en utilisant le multi-threading. – Jason

+0

'strcat' serait une option –

+0

Pourriez-vous peut-être me donner un exemple si ce n'est pas trop de problèmes s'il vous plaît? Je ne sais vraiment pas comment ou où mettre ça :( – Jason