2016-11-14 4 views
1

У меня есть класс растровых изображений, который имеет функцию загрузки для загрузки растрового изображения из любого пути к файлу или идентификатора ресурса. Эта часть работает нормально.SelectObject возвращает NULL с hbitmap, созданным в конструкторе

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 или конструктор растрового изображения, а затем использовать дескриптор в функции рисования.

Если кто-нибудь может предоставить пример загрузки изображения в конструкторе, а затем покрасить его в другом месте в кодах WM_PAINT или эквивалентной функции рисования, я был бы признателен. Код представляет собой новую версию графической библиотеки пользовательского интерфейса GT. Я планирую опубликовать новую версию на codeproject в ближайшие несколько дней или около того. Я должен сначала провести уборку ...

Заранее спасибо.

ответ

0

HINSTANCE параметр LoadImage должен быть 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(); 

Это проверит файл и сразу же закроет дескриптор файла.

Убедитесь, что выбран hbmOld перед удалением hdcMem:

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

Спасибо за вашу помощь. –

 Смежные вопросы

  • Нет связанных вопросов^_^