【问题标题】:SelectObject returns NULL with hbitmap created in constructorSelectObject 使用在构造函数中创建的 hbitmap 返回 NULL
【发布时间】:2017-03-28 13:33:36
【问题描述】:

我有一个位图类,它有一个加载函数,用于从文件路径或资源 ID 加载位图。这部分工作正常。

    void GtBitmap::Load()
    {
        LPTSTR szFileName;
        szFileName = (LPTSTR)m_strPath.c_str();
        // Check for valid .BMP file path
        if (m_strPath.size() > 0)
        {
            // Open .BMP file
            m_pFile = fopen(m_strPath.c_str(), ("rb"));
            if (m_pFile != NULL)
            {

                m_hBitmap = (HBITMAP)LoadImage  (GetModuleHandle(NULL), szFileName, IMAGE_BITMAP, 0, 0, LR_SHARED | LR_LOADFROMFILE);

                GetObject(m_hBitmap, sizeof(m_bmap), &m_bmap);
                int i = 1;
            }   
        }
        else if (m_intResourceID != 0)
        {
            m_hBitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(m_intResourceID), IMAGE_BITMAP, 0, 0, LR_SHARED);
            GetObject(m_hBitmap, sizeof(m_bmap), &m_bmap);
            int i = 1;
        }
    }

但是,当我尝试在我的代码块中呈现它时,SelectObject 返回 null。这是画家类的那部分的代码。

    void  GtPainterGDI::GtDrawBitmap(GtRectI & target, GtBitmap & bitmap, bool blnOffset)
    {
        GtCanvas topCv = m_arrCanvas.back();
        HDC hdcMem = CreateCompatibleDC(topCv.m_hdcParent);
        HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, bitmap.m_hBitmap);
        DWORD lastError = GetLastError();

        bool success = BitBlt(hdcMem, target.GetLeft(), target.GetTop(), 
            target.Width(), target.Height(), hdcMem, 0, 0, SRCCOPY);

        SelectObject(hdcMem, bitmap.m_hBitmap);
        DeleteDC(hdcMem);
    };

SelectObject() 返回 null 并且不绘制图像。如果我在该绘制函数中使用 LoadImage(),我只能显示图像。但是,我不想每次要绘画时都加载图像。我应该能够在位图的Load函数或构造函数中加载一次图像,然后在paint函数中使用句柄。

如果有人可以提供一个在构造函数中加载图像然后在代码 WM_PAINT 或等效绘画函数中绘制它的示例,我将不胜感激。该代码是 GT 图形用户界面库的新版本。我计划在接下来的几天左右在 codeproject 上发布一个新版本。我必须先做一些清理工作......

提前致谢。

【问题讨论】:

    标签: c++ bitmap null loadimage


    【解决方案1】:

    从文件加载图像时,LoadImage 中的HINSTANCE 参数应为NULL。仅在从资源加载时使用GetModuleHandle(NULL)

    m_hBitmap = (HBITMAP)LoadImage(NULL, m_strPath.c_str(), 
        IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    if (!m_hBitmap)
    {
        //report error
    }
    

    这里也不需要LR_SHARED

    当测试文件是否存在时,您可以使用std::ifstream。示例:

    #include <fstream>
    ...
    bool test = std::ifstream(m_strPath).good();
    

    这将测试文件并立即关闭文件句柄。

    确保在删除hdcMem之前选择hbmOld

    HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, bitmap.m_hBitmap);
    BitBlt(...)
    //SelectObject(hdcMem, bitmap.m_hBitmap); <<= remove this
    SelectObject(hdcMem, hbmOld);
    DeleteDC(hdcMem);
    

    【讨论】:

    • 感谢您的帮助。
    猜你喜欢
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 2016-08-03
    相关资源
    最近更新 更多