【问题标题】:Win32 application. HBITMAP LoadImage fails to load anythingWin32 应用程序。 HBITMAP LoadImage 无法加载任何内容
【发布时间】:2014-01-02 06:10:37
【问题描述】:

我正在编写一个函数,可以快速为我正在制作的游戏绘制菜单图像。我可以很好地绘制背景和文本块,但我无法在屏幕上创建位图图像

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;
}

到目前为止,箭头为 NULL,并且我得到了 Load Image Failed 文本框。 我正在使用arrow.bmp的相对路径,我也尝试使用完整路径,但也没有用。

你可能已经注意到这个函数在 WndProc 之外。其他一切都画得很好。 除了arrow.bmp加载之外,我也尝试在那里运行它。

我做错了什么导致arrow.bmp为NULL?我还有其他方法我计划以类似的方式运行,所以让这个函数运行真的很有帮助。

EDIT* 每当我给出完整的路径名时,它仍然无法加载。 这也不是适合 SO 的代码吗?这是我的第一个问题...

EDIT** 附加的 '/' 没有解决问题。

EDIT*** 使用GetLastError,我发现错误代码是2,ERROR_FILE_NOT_FOUND

【问题讨论】:

  • 始终使用文件的完整路径。始终在 SO 问题中发布正确的代码。
  • GetActiveWindow 调用似乎也有点可疑。
  • 应该是L"C:\\Users\\Tim\\Documents\\visual studio 2013\\Projects\\BoulderBisque\\BoulderBisque\\arrow.bmp" 更多的`\`东西。
  • 编写一个小型控制台测试程序,它只会尝试加载图像。
  • 您必须仔细阅读文档。当LoadImage 返回NULL 时,您可以致电GetLastError 了解更多信息。它在文档中写得尽可能清楚。您只需阅读文档。因此,请致电GetLastError 了解更多信息。

标签: c++ winapi bitmap null loadimage


【解决方案1】:

您的问题的早期版本检查了 LoadImage 的返回值,但随后什么也没做。 documentation 是这样说的:

如果函数失败,返回值为NULL。要获取更多错误信息,请致电GetLastError

所以,如果函数失败,请致电GetLastError 找出原因。执行此操作时,您将获得错误代码ERROR_FILE_NOT_FOUND。这是非常确凿的。您指定的文件名不存在。

请注意,问题的最新更新中的代码无条件调用GetLastError。这是一个错误,在 Stack Overflow 上经常出现。该文档仅告诉您在调用LoadImage 失败时调用GetLastError。如果LoadImage调用成功,那么GetLastError返回的值是没有意义的。 Win32 中的错误处理在很大程度上与LoadImage 的处理方式相同,但并非总是如此。所以你必须非常仔细地阅读文档。


也许不是

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

你是说

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

好的,现在你已经找到了正确的路径。对LoadImage 的调用返回NULL,但GetLastError 不再有用并返回ERROR_SUCCESS。这本身就很奇怪。

我认为问题在于您的图像使用了LoadImage 无法理解的格式。我拿了你的 .bmp 文件,在 Paint.net 中加载它,然后重新保存它。一旦我这样做了,重新保存的图像就成功加载了。


与其尝试从文件中加载它,不如将图像链接为资源并以这种方式加载它会更有意义。

【讨论】:

  • 我的文件路径一定有问题,因为我尝试使用的文件确实存在。我确定它拼写正确。我将它包含在 Visual Studio 的资源中以获得确切的路径。因此,如果路径是 C:\Users\Tim\Documents\Visual Studio 2013\Projects\BoulderBisque\BoulderBisque\arrow.bmp 并且相对路径只是 arrow.bmp 第二个参数应该是什么?
  • 好的,所以当我编辑 GetLastError 中的一个 '\' 现在为 0 时,这意味着它成功但箭头仍然为 NULL,所以它仍然失败,当我通过调试器运行它时,它说箭头是NULL 因为 至于无条件调用GetLastError,等我解决了这个问题,我再想想更聪明的办法。
  • 我想我回答了这个问题。代码返回 NULL。我告诉过你如何调用 GetLastError。我告诉你错误是什么意思。我在您的文件名中发现了错误。我不相信函数返回 NULL 并且 GetLastError 为 0。
  • 这是我在调试器中看到的puu.sh/5Mond.png 这是输出窗口puu.sh/5Moos.png
  • 多么真实的传奇! “打开油漆并重新保存图像”工作!!!!!!!!!!!!!!!!!!!!!!!!
【解决方案2】:

我通过对 Gimp 的试验发现,您的 .bmp 文件必须具有以下属性才能使其工作:

  1. depth:24bit
  2. “不显示写入色彩空间信息”框已选中:Gimp export options

如果这仍然不起作用,请尝试“取消阻止”它:File options

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2015-04-12
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多