0

I have a PNG resource stored in a Windows exe. I want to load the png resource and create a pointer to the png data that can be written to disk to create a png file. (FWIW, I don't actually create the file at this point; the data is initially written inside another file and saved as a png file later.) This is in an MFC (c++) project, but the solution doesn't need to use MFC.

I envision a function prototype like this:

void GetPngFromResource(int iResourceID, VOID* pPngFileData, DWORD* pwPngDataBytes);

I see that ::LoadBitmap(), ::LoadImage() and CImage::LoadFromResource() don't support png resource loading. When I do attempt to use LoadImage(), GetLastError() reports "The specified resource name cannot be found in the image file" (error 1814):

HBITMAP hBitmapImage = (HBITMAP)::LoadImage(::GetModuleHandle(0), MAKEINTRESOURCE(iResourceID), IMAGE_BITMAP, 0, 0, 0);

I know the resource exists, because I can get a handle to it using FindResource() (although I don't know how, or whether it is possible, to get the png file data from the HRSCR handle):

HRSCR h = FindResource(HINST_THISCOMPONENT, MAKEINTRESOURCE(iResourceID), L"PNG");

I have seen examples that create an HBITMAP from a png resource using gdi+, but I need to end up with png file data.

Thanks!

Steve A
  • 1,798
  • 4
  • 16
  • 34
  • FindResource followed by LoadResource followed by LockResource used to be the way to do this. But my knowledge maybe years out of date. – john Jul 01 '20 at 17:58
  • John, I've seen sample code that uses those functions to load a png from a resource and create an HBITMAP (but not a png). I suspect that's the right direction, but way beyond my know-how. – Steve A Jul 01 '20 at 18:01
  • LockResource gives you are pointer to the resource data. At that point you're on your own. But you should just be able to use that pointer along with the resource size to create your file. – john Jul 01 '20 at 18:03
  • There's a SizeofResource function to give you the size in bytes of the resource. – john Jul 01 '20 at 18:05
  • If you don't want a Bitmap, then what is all this GDI stuff? – Michael Chourdakis Jul 01 '20 at 18:07
  • John, that worked wonderfully! I posted an answer, but you're welcome to copy and post my answer and I'll change the accepted answer to your post (if SO lets me do that). Thanks! – Steve A Jul 01 '20 at 19:18

1 Answers1

2

"john" deserves credit for this correct solution, as he led me to it (via comments) [yeah, the SO gods marked my question as a duplicate and I can't select this as the solution, but it is].

void GetPngFromResource(int iResourceID, void** ppPngFileData, DWORD* pwPngDataBytes)
{
    HMODULE hMod = GetModuleHandle(NULL);
    HRSRC hRes = FindResource(hMod, MAKEINTRESOURCE(iResourceID), _T("PNG"));
    HGLOBAL hGlobal = LoadResource(hMod, hRes);
    *ppPngFileData = LockResource(hGlobal);
    *pwPngDataBytes = SizeofResource(hMod, hRes);
}

I've excluded error trapping for brevity.

Steve A
  • 1,798
  • 4
  • 16
  • 34