6

I'm writing a function that quickly draws an image of a menu for a game I'm making. I'm able to draw the background and text blocks just fine but I'm having trouble creating a bitmap image on the screen

bool menu::drawMenu(PAINTSTRUCT ps)
{
HWND hWnd = GetActiveWindow();
HDC hdc = GetDC(hWnd), hdcMem;

//Draw a new background

HPEN blackPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
HBRUSH blackBrush = CreateSolidBrush(RGB(0, 0, 0));
SelectObject(hdc, blackPen);
SelectObject(hdc, blackBrush);
Rectangle(hdc, 0, 0, 1080, 720);

//insert selection text

TextOut(hdc, 30, 0, L"New Game", 8);
TextOut(hdc, 30, 30, L"Exit Game", 9);

//draw arrow sprite

HBITMAP arrow = (HBITMAP)LoadImage(NULL, L"C:\\Users\\Tim\documents\\visual studio 2013\\Projects\\BoulderBisque\\BoulderBisque\\arrow.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    DWORD lastError = GetLastError();
if (arrow == NULL)
{
    TextOut(hdc, 0, 60, L"Image Load Failed", 17);
    return false;
}
hdcMem = CreateCompatibleDC(hdc);
if (hdcMem == NULL)
{
    TextOut(hdc, 0, 90, L"Memory Creation Failed", 22);
    return false;
}
SelectObject(hdcMem, arrow);
BitBlt(hdc, 0, choice * 30, 16, 16, hdcMem, 0, 0, SRCCOPY);

//cleanup

ReleaseDC(hWnd, hdc);
DeleteDC(hdcMem);

return true;
}

As of now arrow is NULL and I get the Load Image Failed textbox. I am using the relative path of arrow.bmp I also tried using a full path, that didn't work either.

You may have noticed that this function is outside the WndProc. Everything else draws fine. I tried running it in there too everything but the arrow.bmp loads.

What am I doing wrong to cause arrow.bmp to be NULL? I have other methods I plan to run in similar ways so getting this function to run would really be a big help.

EDIT* Whenever I give the full path name it still fails to load. Also is this not the appropriate code for SO? This is my first question...

EDIT** The aditional '/'s haven't fixed the issue.

EDIT*** Using GetLastError, I found the error code to be 2, ERROR_FILE_NOT_FOUND

user1919573
  • 71
  • 1
  • 1
  • 4

2 Answers2

6

Your early versions of the question checked the return value of LoadImage but then did nothing more. The documentation says this:

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

So, if the function fails, call GetLastError to find out why. When you do so, you obtain the error code ERROR_FILE_NOT_FOUND. Which is pretty conclusive. The filename that you specified does not exist.

Do note that the code in the latest update to the question calls GetLastError unconditionally. That is a mistake, one that is seen all too frequently here on Stack Overflow. The documentation only tells you to call GetLastError when the call to LoadImage fails. If the call to LoadImage succeeds, then the value return by GetLastError is meaningless. Error handling in Win32 is largely handled in the same way as LoadImage does it, but not always. So you have to read the documentation very carefully.


Perhaps instead of

C:\\Users\\Tim\documents\\...

you meant

C:\\Users\\Tim\\documents\\...

OK, now you've got the path right. The call to LoadImage returns NULL, but GetLastError is no longer helpful and returns ERROR_SUCCESS. Which is weird in itself.

I believe that the problem is that your image uses a format that LoadImage does not understand. I took your .bmp file, loaded it in Paint.net and then re-saved it. Once I did that, the re-saved image was loaded successfully.


Rather than trying to load this from a file it would make far more sense to link the image as a resource and load it that way.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    There must be a problem with my file path because the file I'm trying to use does exist. I'm sure it's spelled correctly. I included it in the resources on Visual Studio to get the exact path. So if the path is C:\Users\Tim\Documents\Visual Studio 2013\Projects\BoulderBisque\BoulderBisque\arrow.bmp and the relative path is just arrow.bmp what should that second argument be? – user1919573 Dec 14 '13 at 15:44
  • Okay so when I edited that one '\' in the GetLastError is now 0 which means it succeeds but arrow is still NULL so it still failed, when I run it through the debugger it says that arrow is NULL because As for calling GetLastError unconditionally, I'll think of something more clever to do with it after I sort this issue out. – user1919573 Dec 14 '13 at 16:06
  • I think I answered the question. The code returned NULL. I told you how to call GetLastError. I told you what the error meant. I found the error in your filename. I don't believe you that the function returns NULL and GetLastError is 0. – David Heffernan Dec 14 '13 at 16:12
  • Here is what I see in the debugger http://puu.sh/5Mond.png And here is the output window http://puu.sh/5Moos.png – user1919573 Dec 14 '13 at 16:18
  • Well, that's very strange indeed. Can you put the bmp on a file share site please? – David Heffernan Dec 14 '13 at 16:19
  • http://i.imgur.com/CzNg7zu.png That's not right though, it should be a small blue arrow, but when uploaded it's blank. I also uploaded it to mediafire http://www.mediafire.com/download/fsibq2i1avhp9q3/arrow.bmp – user1919573 Dec 14 '13 at 16:25
  • The image format is not recognised by `LoadImage`. See my latest update. – David Heffernan Dec 14 '13 at 16:33
  • Well there it is, a beautiful 16x16 image and no failures. Hey I appreciate all your help on this. Thanks a lot man! – user1919573 Dec 14 '13 at 16:42
  • Glad I could help. Thanks for the accept. My strong advice here is to add it as a resource and avoid trying to deploy the image files alongside the executable – David Heffernan Dec 14 '13 at 16:43
  • I also encountered a similar problem. LoadImage returned NULL but GetLastError returned success (0). I re-saved the image as advised here and it worked. Thanks! – yushi Oct 07 '19 at 03:51
  • 1
    What a true legend! The "open paint and resaved the image" worked!!!!!!!!!!!!!!!!!!!!!!!!!! – LuisDev99 Feb 13 '20 at 06:10
0

I found through experimenting with Gimp, that your .bmp file must have the following attributes in order for it to work:

  1. depth:24bit
  2. "Do not show write color space information" box checked: Gimp export options

If that still doesn't work then try to "unblock" it: File options.

Yun
  • 3,056
  • 6
  • 9
  • 28
ruutis
  • 3
  • 2