Click here to Skip to main content
15,885,141 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to obtain a HBITMAP using LoadImageW, retrieving an image from embedded resources. LoadImageW returns NULL, with GetLastError() invalidly claiming that access was denied with error 5.

The image definitely exists, and has no special access permissions; I gave full access to all users and the issue persists.

The bitmap is just a simple 32-bit bitmap created with paint.net.

Code:
HINSTANCE h_inst = GetModuleHandle(NULL);
HBITMAP hBitmap = (HBITMAP)LoadImageW(h_inst, MAKEINTRESOURCEW(TEST_IMAGE), IMAGE_BITMAP, 0, 0, 0);

resources.h contains:
#define TEST_IMAGE 102

resources.rc contains:
#include "resources.h"
TEST_IMAGE BITMAP "C:\\full\\path\\to\\image.bmp"

resources.res is generated using windres, and that results in no errors. Opening the file in a hex viewer, everything seems to be fine.

LoadImageW is being used exactly as the documentation states it should. A resource ID of 102 is within the valid range. The image exists and has completely open permissions, so access cannot possibly be denied. So;

1. Why is LoadImageW failing?
2. Why is Windows giving the wrong error message?

What I have tried:

All details already in question
Posted
Updated 12-Sep-22 14:37pm
v2

I have done a bit of searching and I have seen this sequence of code several times :
C++
HRSRC resrc = FindResource( hInstance, MAKEINTRESOURCE( resource ), TEXT("PNG") );
HGLOBAL hPng = LoadResource( hInstance, resrc );
PVOID pByte = LockResource( hPng );
So maybe you should call FindResource to see if it is really there. You can also use Resource Hacker[^] to verify this.

However, I have also read several places that one can not use a PNG file directly in a resource script so I think the answer is it can be embedded as a binary byte stream and then it has to be decoded. The code above will obtain a pointer to that byte stream so it then needs to be decoded. What that means is LoadImage can not be used with a PNG file. It has to be a BMP, CUR, or ICO.

I am not certain of this but that is what my searching has indicated so far.
 
Share this answer
 
Comments
sorauts 12-Sep-22 21:47pm    
I did come to a conclusion and answer the question but it's hidden for moderation. Essentially, it seems that my method works fine for 24-bit bitmaps, but fails for 32-bit ones. I need that transparency, so the only option is using PNG. LoadImage and LoadBitmap don't support PNG, so I'm using FindResource with L"PNG" and PNG in the .rc. None of this is explained anywhere on the internet so it was all trial, error and assumptions. At least I've found a method that works now.
merano99 13-Sep-22 7:32am    
Loadimage is based on GDI+ and that supports many formats such as: BMP, GIF, JPG, PNG, TIFF, WMF, EMF, ICON.
The description "simple 32 bit bitmap" had me wondering a bit. All the usual "simple" 24 bit data formats work. The requirement that transparency is also required was not in the description.
Otherwise LoadResource() was also the solution. my 5!
Turns out LoadImage and LoadBitmap don't work for 32-bit bitmaps, only 24-bit (without alpha). That is not explained anywhere and I figured it out through hours of trial and error. I need transparency, so I instead have to use LoadResource.
 
Share this answer
 
v2
Comments
[no name] 13-Sep-22 8:45am    
Use LoadImage instead with the LR_CREATEDIBSECTION flag set.

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadimagew

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900