Загрузка ICO, BMP, JPG, GIF, TIF, PNG из ресурсной DLL CUIX

Автор Тема: Загрузка ICO, BMP, JPG, GIF, TIF, PNG из ресурсной DLL CUIX  (Прочитано 6668 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Sergey_KАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 114
  • Карма: 2
Код - C++ [Выбрать]
  1. // файл ресурса DLL example_Resource.rc
  2.  ...
  3. // RCDATA
  4.  RCDATA_16_ICO    RCDATA       "path\\sample_16.ico"
  5.  RCDATA_32_BMP   RCDATA       "path\\sample_32.bmp"
  6.  RCDATA_48_JPG    RCDATA       "path\\sample_48.jpg" // нет альфа-канала
  7.  RCDATA_64_GIF    RCDATA       "path\\sample_64.gif"
  8.  RCDATA_128_TIF   RCDATA       "path\\sample_128.tif"
  9.  RCDATA_256_PNG  RCDATA       "path\\sample_256.png"
  10.  ...
  11. // Icon
  12.  IDS_ICON                ICON         "path\\sample.ico"
  13. // Bitmap
  14.  IDS_BMP_ANYSIZE         BITMAP       "path\\sample.bmp"
  15.  ...
  16.  
  17. // класс ресурса (загрузка из файла, DLL или
  18. //текущего процесса (hInst = nullptr)
  19. // для загрузки из секции ресурса ICON или BITMAP
  20. // установить pType соответственно = RT_ICON или RT_BITMAP
  21. // Если ресурс используется в CUIX, идентификатор ресурса
  22. // должен иметь только строковое значение
  23. // и находиться в секции RCDATA
  24. // Иначе может использоваться цифровой идентификатор,
  25. // определённый в resource.h :
  26.  #define IDS_ICON              124
  27.  #define IDS_BMP_ANYSIZE 125
  28.  #define RCDATA_256_PNG  126
  29.  
  30. class GdiPlusBmpResource {
  31. public:
  32.    GdiPlusBmpResource() : m_pBitmap(nullptr), m_hBuffer(nullptr) {  }
  33.    GdiPlusBmpResource (PCWSTR pFile,
  34.       BOOL useEmbeddedColorManagement = FALSE) :
  35.       m_pBitmap(nullptr), m_hBuffer(nullptr) {
  36.       LoadFromFile(pFile, useEmbeddedColorManagement); }
  37.    GdiPlusBmpResource (PCWSTR pName,
  38.       HMODULE hInst = nullptr, PCWSTR pType = RT_RCDATA) :
  39.       m_pBitmap(nullptr), m_hBuffer(nullptr) {
  40.       Load(pName, hInst, pType);
  41.    }
  42.    GdiPlusBmpResource(UINT id, HMODULE hInst = nullptr,
  43.       PCWSTR pType = RT_RCDATA) :
  44.       m_pBitmap(nullptr), m_hBuffer(nullptr) {
  45.       Load(MAKEINTRESOURCE(id), hInst, pType);
  46.    }
  47.    ~GdiPlusBmpResource() { Empty(); }
  48.    bool LoadFromFile(PCWSTR pFile,
  49.      BOOL useEmbeddedColorManagement = FALSE) {
  50.       Empty();
  51.       m_pBitmap = Gdiplus::Bitmap::FromFile(pFile,
  52.           useEmbeddedColorManagement);
  53.       return (m_pBitmap->GetLastStatus() == Gdiplus::Ok);
  54.    }
  55.    bool Load(PCWSTR pName, HMODULE hInst = nullptr,
  56.       PCWSTR pType = RT_RCDATA );
  57.    bool Load(UINT id, HMODULE hInst = nullptr, PCWSTR pType = RT_RCDATA) {
  58.       return Load(MAKEINTRESOURCE(id), hInst, pType);
  59.    }
  60.    void Empty() {
  61.       if (m_pBitmap) {
  62.          delete m_pBitmap;
  63.          m_pBitmap = nullptr;
  64.       }
  65.       if (m_hBuffer) {
  66.          ::GlobalUnlock(m_hBuffer);
  67.          ::GlobalFree(m_hBuffer);
  68.          m_hBuffer = nullptr;
  69.       }
  70.    };
  71.    inline bool isValid() { return m_pBitmap != nullptr; }
  72.    inline Gdiplus::Bitmap* GetBitmap()  const { return m_pBitmap; }
  73.    inline operator Gdiplus::Bitmap*()   const { return m_pBitmap; }
  74.    inline Gdiplus::Bitmap* operator->() const { return m_pBitmap; }
  75. private:
  76.    Gdiplus::Bitmap *m_pBitmap;
  77.    HGLOBAL m_hBuffer;
  78. };
  79.  
  80. bool GdiPlusBmpResource::Load(PCWSTR pName, HMODULE hInst, PCWSTR pType) {
  81.    Empty();
  82.    HRSRC hResource = ::FindResource(hInst, pName, pType);
  83.    if (hResource) {
  84.       DWORD imageSize = ::SizeofResource(hInst, hResource);
  85.       if (imageSize) {
  86.          const void* pResourceData =
  87.              ::LockResource(::LoadResource(hInst, hResource));
  88.          if (pResourceData && (m_hBuffer =
  89.              ::GlobalAlloc(GMEM_MOVEABLE, imageSize))) {
  90.             void* pBuffer = ::GlobalLock(m_hBuffer);
  91.             if (pBuffer) {
  92.                CopyMemory(pBuffer, pResourceData, imageSize);
  93.                IStream* pStream(nullptr);
  94.                if (::CreateStreamOnHGlobal(m_hBuffer, FALSE, &pStream)
  95.                     == S_OK) {
  96.                   if (m_pBitmap = Gdiplus::Bitmap::FromStream(pStream)) {
  97.                      pStream->Release();
  98.                      if (m_pBitmap->GetLastStatus() == Gdiplus::Ok)
  99.                         return true;
  100.                      delete m_pBitmap;
  101.                      m_pBitmap = nullptr;
  102.                   }
  103.                }
  104.                ::GlobalUnlock(m_hBuffer);
  105.             }
  106.             ::GlobalFree(m_hBuffer);
  107.             m_hBuffer = nullptr;
  108.          }
  109.       }
  110.    }
  111.    return false;
  112. }
  113.  
  114. GdiPlusBmpResource* exampleSetIcon(PCWSTR name, HMODULE inst,
  115.       HMENU hmenu, int submenu, int menuItemID) {
  116.  
  117.    GdiPlusBmpResource *bmp(nullptr);
  118.    CMenu menu;
  119.  
  120.    if (menu.Attach(hmenu)) {
  121.       bmp = new GdiPlusBmpResource(name, inst, RT_RCDATA);
  122.       if (bmp && bmp->isValid()) {
  123.          MENUITEMINFO menuiteminfo = { 0 };
  124.          menuiteminfo.cbSize = sizeof(menuiteminfo);
  125.          menuiteminfo.fMask |= MIIM_ID | MIIM_DATA |
  126.             MIIM_STRING | MIIM_FTYPE;
  127.          WCHAR buf[MAX_PATH];
  128.          menuiteminfo.dwTypeData = buf;
  129.          menuiteminfo.cch = MAX_PATH;
  130.          if (menu.GetSubMenu(submenu)->GetMenuItemInfo(menuItemID,
  131.                 &menuiteminfo)) {
  132.             menuiteminfo.fType |= MFT_OWNERDRAW;
  133.             menuiteminfo.dwItemData =
  134.                 reinterpret_cast<ULONG_PTR> (bmp->GetBitmap());
  135.             if (menu.GetSubMenu(submenu)->SetMenuItemInfo(menuItemID,
  136.                 &menuiteminfo)) {
  137.                menu.Detach();
  138.                return bmp;
  139.             }
  140.          }
  141.          delete bmp;
  142.       }
  143.       menu.Detach();
  144.    }
  145.    return nullptr;
  146. }
  147.  
  148. //Пример загрузки иконки и установки на пункт меню
  149. CString path;
  150. path.GetEnvironmentVariableW(_T("USERPROFILE"));
  151. path.Append(_T("\\Autodesk\\Resource.dll"));
  152. HMODULE resource= ::LoadLibrary(path);
  153. if (resource) {
  154.    GdiPlusBmpResource *menuIdBmp = exampleSetIcon(_T("RCDATA_16_ICO"),
  155.     resource, myMenuHandle, subMenuNumer, menuItemID);
  156.    ::FreeLibrary(resource);
  157. }
  158.  

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Спасибо за готовый код. У меня только одно небольшое замечание. Вместо LoadLibrary в случае работы только с ресурсами лучше использовать LoadLibraryEx с флагом LOAD_LIBRARY_AS_DATAFILE - это работает быстрее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Sergey_KАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 114
  • Карма: 2
Точней наверно будет:
LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE