【问题标题】:Win32 Bitmap won't loadWin32 位图无法加载
【发布时间】:2013-09-13 08:15:17
【问题描述】:

我有这段代码来加载位图:

HBITMAP reg_hbmCS = NULL;

LRESULT CALLBACK WndProc(HWND hRegWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_CREATE:
        reg_hbmCS = LoadBitmap(NULL, MAKEINTRESOURCE(IDB_CSBITMAP));
        if(!reg_hbmCS)
            MessageBox(hRegWnd,
                "No se ha podido cargar el icono del programa.\r\n"
                "Pruebe a reinstalar el programa para solucionar este problema.",
                "Atención", MB_ICONEXCLAMATION | MB_OK);
        break;
    case WM_CLOSE:
        DeleteObject(reg_hbmCS);
        DestroyWindow(hRegWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hRegWnd, message, wParam, lParam);
    }

    return 0;
}

问题是 reg_hbmCS 无法加载,所以我没有可用的位图(它在(if !reg_hbmCS) 中显示消息框。

这里是我的资源.h:

#ifndef RESOURCES_H
#define RESOURCES_H

#ifndef IDC_STATIC
#define IDC_STATIC      -1
#endif

#define IDI_CSICO       101

#define IDB_CSBITMAP    201

#endif // RESOURCES_H

还有我的 resources.rc:

#include <windows.h>
#include "resources.h"

IDI_CSICO ICON "CS-Nursing.ico"

IDB_CSBITMAP BITMAP DISCARDABLE "CS-Nursing.bmp"

如果有必要,我在 WindowsXP SP3 上使用 Code::Blocks 12.11。 任何帮助将不胜感激。

【问题讨论】:

  • 这是在 DLL 还是 EXE 中? DLL 需要在 dll 加载时缓存 HINSTANCE,以便对 LoadBitmap (et.al.) 的调用转到 DLL 的资源,而不是调用 EXE 的资源。
  • 您是否使用资源查看器/编辑器验证您的位图实际上已被编译到可执行文件中?
  • 还要确保您的位图有效。许多工具会生成带有无效位图标题的位图。在 MS Paint 中打开位图并再次保存。
  • 这是一个EXE,正在编译:windres.exe -J rc -O coff -i C:\DOCUME~1\ADMINI~1\MYDOCU~1\CS-NUR~1\ RESOUR~1.RC -o obj\Debug\resources.res mingw32-g++.exe -o bin\Debug\CS-Nursing.exe obj\Debug\main.o obj\Debug\resources.res -lgdi32 -luser32 -lkernel32 -lcomctl32 输出大小为 758.79 KB 我必须检查位图的有效性。
  • 用MS Paint打开位图,再次保存,还是没有加载。

标签: c winapi win32gui


【解决方案1】:

LoadBitmap 可能会失败,因为您没有告诉它在哪里可以找到位图资源。 LoadBitmap 的第一个参数是包含位图资源的模块实例的句柄(除非您正在加载系统位图,在这种情况下它为 NULL)。由于位图资源正在编译到您的应用程序中,因此您需要在调用 LoadBitmap 时将句柄作为第一个参数传递给应用程序模块的实例。您可以从 WinMain 函数中的第一个参数获取此句柄。许多人将此参数存储在全局变量中,以便可以从其他函数轻松访问它。如果对 LoadBitmap 的调用仍然失败,那么您应该调用 GetLastError 来获取描述调用失败原因的代码。见Windows System Error Codes

【讨论】:

  • 添加了“HINSTANCE hRegisInstance;”作为全局和 "hRegisInstance = (HINSTANCE)GetWindowLong(hRegWnd, GWL_HINSTANCE); // "reg_hbmCS = LoadBitmap(hRegisInstance, MAKEINTRESOURCE(IDB_CSBITMAP));" 但仍然没有加载它,我会寻找 GetLastError跨度>
  • 抱歉耽搁了,我为 GetLastError() 添加了一个函数,我得到“没有记录错误消息”,这意味着错误消息为“0”,从程序开始到结束。
  • 您应该调用 GetWindowLongPtr 而不是 GetWindowLong,因为在 64 位版本的 Windows 上,GWL_HINSTANCE 可能大于 long。当 GetLastError 返回零时,并不意味着自程序启动以来没有发生错误,这意味着设置错误代码的最后一个 Windows API 函数将其设置为零。因此,当您需要调用 GetLastError 来了解函数调用失败的原因时,您必须确保在调用 GetLastError 之前没有调用任何 Windows API 函数(至少不是任何设置错误代码的函数)。
【解决方案2】:

更改了 resources.rc 文件:

//IDB_CSBITMAP BITMAP DISCARDABLE "CS-Nursing.bmp"
IDB_CSBITMAP BITMAP "CS-Nursing.bmp"

现在完美运行,将其标记为已解决,谢谢大家的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 2015-12-23
    相关资源
    最近更新 更多