2010-06-09 5 views
6

Comment charger une ressource png dans un CBitMap? Lorsque j'essaie cela, ça ne marche pas.Charger une ressource png dans un CBitMap

CImage image; 
image.LoadFromResource(AfxGetInstanceHandle(), IDB_PNG1); 
bitmap.Attach(image.Detach()); 

Il me donne un type de ressource d'erreur non trouvé. Existe-t-il un autre moyen de charger une ressource PNG?

+0

L'erreur est-elle dans LoadFromResource ou dans Attach? – dwo

Répondre

5

LoadFromResource utilise LoadImage en interne, il ne prend pas en charge PNG la dernière fois que j'ai essayé, malgré ce que la documentation indique. Vous pouvez lier avec CxImage (regardez sur codeproject) mais c'est beaucoup de travail pour peu de bénéfice réel. Ce que j'ai fait à la fin, c'était oublier le format PNG, utiliser AlphaConv pour convertir les fichiers PNG en bitmaps Windows 32 bits et utiliser CImage avec ceux-ci. L'avantage supplémentaire est que vous pouvez les utiliser avec CBitmapButton etc. dans MFC sans aucune transformation.

Une autre façon de contourner le problème est d'extraire le contenu de la ressource dans un fichier temporaire, puis d'utiliser CImage :: Load pour le lire à partir de là. Si je vous attrapais dans l'une de mes bases de code, je vous frapperais dans le visage;)

+2

+1 pour un développeur qui va vraiment défendre sa base de code – Lothar

1

Utilisez une bibliothèque comme CxImage (http://www.xdp.it/cximage.htm) pour faire tout le travail de levage pour vous. Le code devient aussi simple que: -

CxImage image; 
if (image.LoadResource(<resource_instance_handle>, <resource_id>, CXIMAGETYPE_PNG)) 
{ 
    HBITMAP hbmp = image.CreateHBITMAP(); 
    ... do something with hbmp ... 
} 

(notez que je vous écris ce code de la mémoire - vous devrez peut-être modifier légèrement pour le faire fonctionner!)

J'utilise un CxImage beaucoup pour les graphiques dans mes programmes et cela simplifie énormément les choses.

16

Si vous utilisez VS2008 ou plus récent (MFC Feature Pack) vous pouvez utiliser CPngImage qui dérive de CBitmap et est contenu dans <afxtoolbarimages.h>

CPngImage image; 
image.Load(AfxGetInstanceHandle(), IDB_PNG1); 
bitmap.Attach(image.Detach()); 
+1

Bonne trouvaille! Je voudrais qu'il soit mieux documenté, j'aurais vraiment pu l'utiliser pendant des années :( – Roel

+1

Les paramètres sont vice versa: 'image.Load (IDB_PNG1, AfxGetInstanceHandle());' – cwschmidt

2

Si vous ne avez pas vraiment besoin d'un CBitmap, mais seulement une poignée de cette peut vous être utile.

Ou si vous pouvez obtenir un CBitMap à partir de HBITMAP, cette fonction renvoie le bon résultat. Je l'utilise sur une application commerciale et cela fonctionne.

// Based on afxbutton.cpp's static function ButtonLoadBitmap 
HBITMAP __stdcall ButtonLoadBitmap(UINT uiBmpResId) 
{ 
    if (uiBmpResId == 0) 
    { 
     return NULL; 
    } 

    LPCTSTR lpszResourceName = MAKEINTRESOURCE(uiBmpResId); 
    ENSURE(lpszResourceName != NULL); 

    HBITMAP hbmp = NULL; 

    // Try to load PNG image first: 
    CPngImage pngImage; 
    if (pngImage.Load(lpszResourceName)) 
    { 
     hbmp = (HBITMAP) pngImage.Detach(); 
    } 
    else 
    { 
     HINSTANCE hinstRes = AfxFindResourceHandle(lpszResourceName, RT_BITMAP); 
     if (hinstRes == NULL) 
     { 
      return NULL; 
     } 

     UINT uiLoadImageFlags = LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS; 

     hbmp = (HBITMAP) ::LoadImage(hinstRes, lpszResourceName, IMAGE_BITMAP, 0, 0, uiLoadImageFlags); 
    } 

    return hbmp; 
} 
Questions connexes