2015-08-06 1 views
2

j'ai rencontré ce problème lors de l'écriture d'un jeu de démineur. J'ai utilisé bitmap pour les nombres, les mines et les blancs. Je pense que je l'ai enregistré correctement eux dans le fichier de ressourcesWin32 LoadImage génère l'erreur 1812 et 1813

IDI_0     BITMAP     "D:\\User\\Mark\\Documents\\C++\\win32\\MineSweeper\\MineSweeper\\empty.bmp" 
IDI_1     BITMAP     "D:\\User\\Mark\\Documents\\C++\\win32\\MineSweeper\\MineSweeper\\1.bmp" 
IDI_2     BITMAP     "D:\\User\\Mark\\Documents\\C++\\win32\\MineSweeper\\MineSweeper\\2.bmp" 
IDI_3     BITMAP     "D:\\User\\Mark\\Documents\\C++\\win32\\MineSweeper\\MineSweeper\\3.bmp" 

et le fichier d'en-tête

#define IDI_0       200 
#define IDI_1       201 
#define IDI_2       202 
#define IDI_3       203 

et je les charge comme celui-ci

h0 = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(IDI_0), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); 
h1 = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(IDI_1), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); 
h2 = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(IDI_2), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); 
h3 = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(IDI_3), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); 

J'ai aussi vérifié le fichier exe avec ResourceHacker et trouvé toutes les bitmaps là-bas.

Ce que je ne comprends pas est que seulement parfois (~ 50%) quand je lance le jeu apparaît soit

Error 1812: The specified image file did not contain a resource section. 

ou

Error 1813: The specified resource type cannot be found. 

Mais si je les charge de fichiers comme celui-ci

h0 = (HBITMAP)LoadImage(NULL, L"D:\\User\\Mark\\Documents\\C++\\win32\\MineSweeper\\MineSweeper\\empty.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); 
h1 = (HBITMAP)LoadImage(NULL, L"D:\\User\\Mark\\Documents\\C++\\win32\\MineSweeper\\MineSweeper\\1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); 
h2 = (HBITMAP)LoadImage(NULL, L"D:\\User\\Mark\\Documents\\C++\\win32\\MineSweeper\\MineSweeper\\2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); 
h3 = (HBITMAP)LoadImage(NULL, L"D:\\User\\Mark\\Documents\\C++\\win32\\MineSweeper\\MineSweeper\\3.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); 

tout fonctionne bien.

Des idées ou des conseils seraient appréciés. Merci!

+0

Votre paramètre hInst est peut-être incorrect, vous pouvez enregistrer tous les paramètres et déterminer si la ressource existe avec 'FindResource'. – Jichao

+0

@Jichao Merci pour votre réponse! J'ai utilisé le code de démarrage généré par vs2013, y compris les init de classe de la fenêtre et les registres. Quelque chose que je dois changer là-bas? et des idées pourquoi ça ne va que mal la moitié du temps? –

+0

Juste une supposition; mais seriez-vous prêt à changer LR_CREATEDDIBSECTION à LR_DEFAULTCOLOR? Je ne suis pas familier avec cette valeur. – user3282085

Répondre

0

Je personnellement aurait envisager d'utiliser GDI + pour charger vos images. Vous pouvez toujours charger à partir d'un fichier disque ou de la section ressources de votre application. Il vous donne également l'avantage d'accéder à tous les formats d'image pris en charge par Windows (BMP, GIF, JPEG, PNG, TIFF, Exif, WMF et EMF)

Pour l'utiliser, il vous suffit d'initialiser GDI + en premier puis effectuez un arrêt avant la sortie du programme.

Voici la fonction que j'utilise pour le chargement de fichier disque:

// BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF 
HBITMAP mLoadImageFile(wchar_t *filename) 
{ 
    HBITMAP result = NULL; 
    Bitmap bitmap(filename, false); 
    bitmap.GetHBITMAP(0, &result); 
    return result; 
} 

Si nous avons un fichier de ressources qui contient les éléments suivants:

IDR_PNG1   RT_PNG   ".\\girl.png" 
IDR_JPG1   RT_JPG   ".\\rssLogo.jpg" 

Ensuite, nous pouvons charger chacune des images thusly:

HBITMAP png = loadImgResource(IDR_PNG1, L"RT_PNG"); 
HBITMAP jpg = loadImgResource(IDR_JPG1, L"RT_JPG"); 

aussi les deux fonctions que j'utilise pour charger à partir d'une ressource. Vous remarquerez que je suis définitivement dans GetModuleHandle (0) dans la 2ème fonction - changer si vous voulez lire d'autres de tout module (dll, exe) que celui en cours.

// BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF 
HBITMAP loadImgResource(wchar_t *pName, wchar_t *pType, HMODULE hInst) 
{ 
    Gdiplus::Bitmap *m_pBitmap; 
    HBITMAP result=NULL; 

    HRSRC hResource = FindResource(hInst, pName, pType); 
    if (!hResource) 
     return NULL; 

    DWORD imgSize = SizeofResource(hInst, hResource); 
    if (!imgSize) 
     return NULL; 

    const void *pResourceData = LockResource(LoadResource(hInst, hResource)); 
    if (!pResourceData) 
     return NULL; 

    HANDLE m_hBuffer = GlobalAlloc(GMEM_MOVEABLE, imgSize); 
    if (m_hBuffer) 
    { 
     void* pBuffer = GlobalLock(m_hBuffer); 
     if (pBuffer) 
     { 
      CopyMemory(pBuffer, pResourceData, imgSize); 
      IStream* pStream = NULL; 
      if (CreateStreamOnHGlobal(m_hBuffer, FALSE, &pStream) == S_OK) 
      { 
       m_pBitmap = Gdiplus::Bitmap::FromStream(pStream); 
       pStream->Release(); 
       if (m_pBitmap) 
       { 
        if (m_pBitmap->GetLastStatus() == Gdiplus::Ok) 
        { 
         m_pBitmap->GetHBITMAP(0, &result); 
         delete m_pBitmap; 
        } 
       } 
      } 
      GlobalUnlock(m_hBuffer); 
     } 
     GlobalFree(m_hBuffer); 
    } 
    return result; 
} 

HBITMAP loadImgResource(WORD resNum, LPWSTR pType) 
{ 
    return loadImgResource(MAKEINTRESOURCE(resNum), pType, GetModuleHandle(0));//hInst); 
} 
+0

Pourquoi GDI +, et non, disons, le [Composant Windows Imaging] (https://msdn.microsoft.com/en-us/library/windows/desktop/ee719902.aspx)? – IInspectable

+0

(a) Parce que je le connais déjà et (b) parce que le code utilisant WIC semble être lourd d'interface COM. Jamais une chose particulièrement agréable - en particulier avec des outils non-microsoft. Quoi, s'il y a des avantages à utiliser WIC à la place? Est-ce que je peux encore pomper un exe sous 10kb sans avoir recours à des linkers exotiques comme des friands ou des exe-packers comme UPX? – enhzflep

+0

Pourquoi WIC ajouterait-il plus de charge utile via GDI +? Ce n'est pas comme si les décodeurs à la demande étaient liés de manière statique à l'image exécutable. En ce qui concerne le COM impliqué: Vous devez co-créer une usine, demander un décodeur basé sur un flux de fichier, et décoder le ou les cadres qui vous intéressent. Ceci est facilement réalisable, avec n'importe quel jeu d'outils. Voir le [Visionneuse d'image WIC en utilisant l'exemple Direct2D] (https://msdn.microsoft.com/en-us/library/windows/desktop/ee720057.aspx) au cas où vous êtes intéressé. Ou jetez un oeil à certains [exemple de code décodeur] (https://msdn.microsoft.com/en-us/library/windows/desktop/ee719870.aspx). – IInspectable