2010-06-09 12 views
6

¿Cómo cargo un recurso png en un CBitMap? Cuando intento esto, no funciona.Cargar un recurso png en un CBitMap

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

Me da un tipo de recurso de error no encontrado. ¿Hay alguna otra forma de cargar un recurso PNG?

+0

¿Ha aparecido el error en LoadFromResource o en Adjuntar? – dwo

Respuesta

5

LoadFromResource usa LoadImage internamente, no es compatible con PNG la última vez que lo intenté, a pesar de lo que dice la documentación. Puedes vincular con CxImage (mira en codeproject) pero es mucho trabajo para poco beneficio real.

Lo que hice al final fue olvidarse de PNG, usar AlphaConv para convertir archivos PNG en bitmaps de Windows de 32 bits y usar CImage con esos. Una ventaja adicional es que puede usarlos con CBitmapButton, etc. en MFC sin ninguna transformación.

Otra forma de hackearlo es extraer el contenido del recurso en un archivo temporal, luego usar CImage :: Load para leerlo desde allí. Si pudiera atraparte haciendo eso en una de mis bases de código, te golpearía en la cara;)

+2

+1 para un desarrollador que realmente va a defender su base de código – Lothar

1

Usa una biblioteca como CxImage (http://www.xdp.it/cximage.htm) para hacer todo el trabajo pesado por ti. El código se vuelve tan simple como: -

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

(tenga en cuenta que estoy escribiendo este código de la memoria - es posible que tenga que modificar un poco para conseguir que funcione!)

utilizo un CxImage mucho para los gráficos en mis programas y simplifica enormemente las cosas.

16

Si está utilizando VS2008 o más reciente (paquete de características de MFC), puede utilizar CPngImage que se deriva de CBitmap y está contenido en <afxtoolbarimages.h>

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

¡Buen descubrimiento! Desearía que estuviera mejor documentado, realmente podría haber usado esto por años :( – Roel

+1

Los parámetros son viceversa: 'image.Load (IDB_PNG1, AfxGetInstanceHandle());' – cwschmidt

2

Si usted realmente no necesita un CBitmap, pero sólo un mango de esta puede ser útil para ti

O si puede obtener un CBitMap desde el HBITMAP esta función lo devuelve también es bueno.

Lo uso en una aplicación comercial y funciona.

// 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; 
} 
Cuestiones relacionadas