2010-06-09 8 views
6

Come caricare una risorsa png in una CBitMap? Quando lo provo, non funziona.Caricare una risorsa png in una CBitMap

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

Mi dà un tipo di risorsa di errore non trovato. C'è un altro modo per caricare una risorsa PNG?

+0

L'errore è in LoadFromResource o in Attach? – dwo

risposta

5

LoadFromResource utilizza LoadImage internamente, non supporta PNG l'ultima volta che ho provato, nonostante ciò che dice la documentazione. Puoi collegarti con CxImage (vedi codeproject) ma è molto lavoro per un piccolo beneficio reale.

Quello che ho fatto alla fine era dimenticare PNG, usare AlphaConv per convertire i PNG in bitmap Windows a 32 bit e usare CImage con quelli. Un ulteriore vantaggio è che è possibile utilizzarli con CBitmapButton ecc. In MFC senza alcuna trasformazione.

Un altro modo per eseguire l'hacking è estrarre il contenuto della risorsa in un file temporaneo, quindi utilizzare CImage :: Load per leggerlo da lì. Se ti accorgessi di farlo in una delle mie basi di codice, ti darei un pugno in faccia però;)

+2

+1 per uno sviluppatore che difenderà davvero la sua base di codici – Lothar

1

Usa una libreria come CxImage (http://www.xdp.it/cximage.htm) per fare tutto il lavoro pesante per te. Il codice diventa semplice come: -

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

(notare che io sto scrivendo questo codice dalla memoria - potrebbe essere necessario modificarlo leggermente per farlo funzionare!)

io uso un CxImage molto per la grafica nei miei programmi e semplifica enormemente le cose.

16

Se si sta utilizzando VS2008 o più recente (Feature Pack MFC) è possibile utilizzare CPngImage che deriva dalla CBitmap ed è contenuta in <afxtoolbarimages.h>

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

Buona scoperta! Vorrei che fosse documentato meglio, avrei potuto usarlo per anni :( – Roel

+1

I parametri sono viceversa: 'image.Load (IDB_PNG1, AfxGetInstanceHandle());' – cwschmidt

2

Se non si ha realmente bisogno di un CBitmap, ma solo una maniglia questo potrebbe essere utile per te

Oppure se è possibile ottenere una CBitMap da HBITMAP questa funzione restituisce è anche buona.

Lo uso su un'applicazione commerciale e funziona.

// 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; 
} 
Problemi correlati