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
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, callGetLastError
.
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.