1

I have a bitmap class that has a load function for loading the bitmap from either file path or resource ID. This part works fine.

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

However, when I try to render it in my code block, the SelectObject returns null. Here is the code for that section of the painter class.

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

The SelectObject() returns null and the image is not drawn. I can only get the image to show up if I use a LoadImage() in that paint function. However I don't want to load the image every time I want to paint. I should be able to load the image once in the Load function or constructor of the bitmap, then use the handle in the paint function.

If anyone could please provide an example of loading an image in a constructor and then painting it elsewhere in the codes WM_PAINT or equivalent painting function I would appreciate it. The code is a new version of the GT graphical user interface library. I plan on posting a new version on codeproject in the next few days or so. I have to do some cleanup first...

Thanks in advance.

1 Answers1

0

HINSTANCE parameter in LoadImage should be NULL when loading the image from file. Use GetModuleHandle(NULL) only when loading from resource.

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

Also LR_SHARED is not necessary here.

When testing for file's exist, you can use std::ifstream. Example:

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

This will test for file and close the file handle right away.

Make sure to select hbmOld before deleting hdcMem:

HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, bitmap.m_hBitmap);
BitBlt(...)
//SelectObject(hdcMem, bitmap.m_hBitmap); <<= remove this
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77