Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load a png resource into picture control on a dialog box?

I tried the following code on OnInitDialog() but nothing was shown.

m_staticLogo.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(IDB_LOGO)));

where m_staticLogo is the static picture control and IDB_LOGO is the resource ID of the png file.

like image 481
david.healed Avatar asked Oct 21 '10 14:10

david.healed


People also ask

How do I add an image control in MFC Dialog?

Step 1 − Right-click on the dialog in the designer window and select Insert ActiveX Control. Step 2 − Select the Microsoft Picture Click Control and click OK. Step 3 − Resize the Picture control and in the Properties window, click the Picture field. Step 4 − Browse the folder that contains Pictures.

How can we display an icon or a bitmap image on the button control?

Steps for assigning bitmap to button in mfc :Create object of bitmap. Load bitmap by using LoadBitmap() Get Handle of button using id and GetDlgItem() method. Modify style so that we can assign bitmap to it.


2 Answers

For those, who need quick solution, here is a way to load png file from resources using GDI+ (original answer for standard GDI from here - http://www.codeproject.com/Questions/377803/How-to-load-PNG-images-in-mfc):

bool GdiPlusUtils::LoadBitmapFromPNG(UINT uResourceID, 
    Bitmap** ppBitmapOut, HINSTANCE hInstance /*= NULL*/)
{
    bool bRet = false;

    if (!hInstance)
        hInstance = AfxGetInstanceHandle();

    HRSRC hResourceHandle = ::FindResource(
        hInstance, MAKEINTRESOURCE(uResourceID), L"PNG");
    if (0 == hResourceHandle)
    {
        return bRet;
    }

    DWORD nImageSize = ::SizeofResource(hInstance, hResourceHandle);
    if (0 == nImageSize)
    {
        return bRet;
    }

    HGLOBAL hResourceInstance = ::LoadResource(hInstance, hResourceHandle);
    if (0 == hResourceInstance)
    {
        return bRet;
    }

    const void* pResourceData = ::LockResource(hResourceInstance);
    if (0 == pResourceData)
    {
        FreeResource(hResourceInstance);
        return bRet;
    }

    HGLOBAL hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, nImageSize);
    if (0 == hBuffer)
    {
        FreeResource(hResourceInstance);
        return bRet;
    }

    void* pBuffer = ::GlobalLock(hBuffer);
    if (0 != pBuffer)
    {
        CopyMemory(pBuffer, pResourceData, nImageSize);
        IStream* pStream = 0;
        if (S_OK == ::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream))
        {
            *ppBitmapOut = new Bitmap(pStream);
            pStream->Release();
            bRet = true;
        }
        ::GlobalUnlock(hBuffer);
    }
    ::GlobalFree(hBuffer);

    UnlockResource(hResourceInstance);
    FreeResource(hResourceInstance);

    return bRet;
}

You can add png file as resource using Add Resource command and in the panel choose Import.

like image 110
Michal Pokluda Avatar answered Oct 19 '22 09:10

Michal Pokluda


As you’ve discovered, ::LoadBitmap (and the newer ::LoadImage) only deal with .bmps. By far the easiest solution is to convert your image to a .bmp.

If the image has transparency, it can be converted into a 32-bit ARGB bitmap (here is a tool called AlphaConv that can convert it). Then load the image using the CImage class LoadFromResource method. Pass the CImage to m_staticLogo.SetBitmap().

But if you really need it to be a .png, it can be done.

Method 1 (the easier way): Load the .png from a file using CImage::Load. Pass the CImage to m_staticLogo.SetBitmap().

Method 2 (the harder way): Load the .png from a resource by loading the resource into a COM IStream and using CImage::Load. (NOTE: CImage::LoadFromResource looks tempting but will not work with a .png graphic). To get the resource into a COM IStream, see this Codeproject article. Note the article works with Gdiplus::Bitmap but the key part is how to create the IStream, which you should be able to adapt for CImage. Finally, pass the CImage to m_staticLogo.SetBitmap().

Edit: Updated to use CImage, which is easier than Gdiplus::Bitmap.

like image 16
Nate Avatar answered Oct 19 '22 11:10

Nate