【问题标题】:(Bitmap)LoadImage() returns NULL and GetLastError() returns 0(Bitmap)LoadImage() 返回 NULL 并且 GetLastError() 返回 0
【发布时间】:2020-01-28 19:55:27
【问题描述】:

我正在尝试在窗口上绘制位图文件。所以我使用了 (HBITMAP)LoadImage() 它返回 NULL。 我使用 GetLastError 来查看问题,但它也返回 0。 我正在开发 goorm ide(Windows 应用程序)。

    HBITMAP hBitmap = NULL;
    hBitmap = (HBITMAP)LoadImageW( NULL, L"C:\\Users\\Asd\\Downloads\\image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );

    if(hBitmap == NULL){
        DWORD errorCode = GetLastError();
        if(errorCode != 0){
            LPSTR messageBuffer = nullptr;
            FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                NULL,
                errorCode,
                0,
                (LPTSTR)&messageBuffer,
                0,
                NULL);
                MessageBox(NULL, messageBuffer, "hBitmap is NULL!" , MB_OK);
                }else{
                    MessageBox(NULL, "hBitmap is null but errorCode is 0", "???" , MB_OK);
                }
            }

如果我在代码中将“image.bmp”更改为“asdf.bmp”,它会显示“没有文件”。所以我确定它找到了文件,但似乎无法正常工作。当我打印位图的宽度和高度时,它显示奇怪的数字(如 12312321、-3453453)。我找不到问题所在。

我也试过这个: (来自https://support.microsoft.com/en-us/help/158898/howto-how-to-use-loadimage-to-read-a-bmp-file

hBitmap = (HBITMAP)LoadImage( NULL, "image.bmp", IMAGE_BITMAP, 0, 0,
               LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );

【问题讨论】:

  • 来自 LoadImageA 函数的文档:“如果 fuLoad 参数包含 LR_LOADFROMFILE 值,lpszName 是包含独立资源(图标、光标或位图文件)的文件的名称。因此,将hinst设置为NULL。”。所以基本上你应该将第一个参数设置为 NULL 而不是尝试获取你的模块。
  • 我试过 hBitmap = (HBITMAP)LoadImage( NULL, "image.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );但仍然是相同的错误消息。
  • @o_weisman HBITMAP 已经是指针类型,使用HBITMAP* 是错误的。并且类型转换不能产生 NULL,除非被转换的值已经是 NULL。
  • @이재원 您是否尝试过使用.bmp 文件的绝对路径?您当前正在使用相对路径。另见LoadImage() returns NULL and GetLastError() returns 0。我注意到的一件事是您的WM_PAINT 代码没有进行任何错误处理,它在第一次绘制后破坏了hBitmap,使hBitmap 对后续绘制无效。由于您在WM_CREATE 中加载了hBitmap,因此您应该在WM_DESTROY 中销毁它。
  • @이재원 然后缺少其他一些内存错误,逻辑罪魁祸首可能是.bmp 文件本身的问题。您是否尝试过使用其他 .bmp 文件?

标签: c++ winapi


【解决方案1】:

我创建了最简单的 Windows 桌面应用程序。

并且只添加了WM_CREATEWM_PAINT 消息事件。

我添加了自己的bmp图片,可以成功加载图片。

像这样:

hBitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL), L"C:\\Users\\strives\\Desktop\\panda.bmp", IMAGE_BITMAP, 0, 0,
            LR_DEFAULTSIZE | LR_LOADFROMFILE);

从你在cmets中的回答来看,你尝试过使用绝对路径来加载图片,但是你没有考虑到问题。就是图片格式,如果你只是把一张JPG图片的后缀改成.bmp,那么你的hBitmap会返回0,GetLasterror也会返回0。

因此,您所要做的就是使用格式正确的 BMP 图像。如果没有该图片,请使用图片转换格式工具进行转换。

另外,我之前也遇到过类似的post,可以参考一下。

【讨论】:

  • LoadImage() 记录在失败时通过GetLastError() 返回错误代码。它可以报告 0 的事实是一个错误,恕我直言。如果文件不是有效的 BMP 格式,我会期待像 ERROR_INVALID_DATA 或类似的东西。
【解决方案2】:

通过 BOOL LoadBitmap(UINT nIDResource) 和一个 GIMP 创建的 bmp 得到这个。将资源 bmp 文件加载到 Paint 中并进行一些伪更改以使 Paint 相信您更改了 bmp。保存 bmp。问题消失了!我没有深入研究以找到根本原因。 LoadBitmap 不喜欢 GIMP 创建的 bmp 文件。

【讨论】:

  • 除了图像是在 linux 中使用“mogrify -format bmp *.jpg”创建的之外,其他体验相同。底线是 loadimage 对其图像来源非常挑剔。
  • 更奇怪的是:在 wine 中运行可执行文件,使用 GIMP 映像运行良好,但在我的 Windows 机器上失败。在 Paint 中重新保存文件解决了这个问题,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-15
  • 1970-01-01
  • 2011-12-18
  • 1970-01-01
  • 2017-09-16
相关资源
最近更新 更多