Как из ресурсов программы вытащить файл и сделать из него хендл иконки

Тема в разделе "WASM.BEGINNERS", создана пользователем assch, 16 янв 2012.

  1. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Один из способов отображения картинки в программе например формата "Gif" такой.
    Создаёшь дочернее окно.

    Код (Text):
    1. invoke CreateWindowEx,0,addr Static,0,WS_CHILD or WS_VISIBLE or SS_ICON,100,100,80,109,hWnd,0,0,0
    2. mov hHild,eax
    Параметр "SS_ICON" нужен для того чтобы картинка выводилась в формате иконки.
    Этот способ "в некоторых случаях" довольно простой и лёгкий, так как не надо заморачиватся с обработчиком "WM_PAINT",
    функцией "BeginPaint" и других сопутствующих функций.

    Я например делаю так:
    Если указать место положение файла то тандем функций

    Код (Text):
    1. invoke MultiByteToWideChar,0,0,addr szName,-1,addr Unicod,addr Char
    2. invoke GdipLoadImageFromFile,addr Unicod,addr hBitmap
    Вытащит из файла "Bitmap" ну и следующая функция из битмапа сделает "HICON" (надо только не забыть инициализировать библиотеку GDI+)

    i
    Код (Text):
    1. nvoke GdipCreateHICONFromBitmap,hBitmap,addr hIcon
    2. invoke GdipDisposeImage,hBitmap
    Ну и наконец последняя функция даст команду отобразить эту иконку в дочернем окне.

    Код (Text):
    1. invoke SendMessage,hHild,170h,hIcon,0
    Ещё раз напоминаю что это просто один из способов вывода графического контента в окно приложения.
    Относительная лёгкость наверное состоит в том что формат иконки не сжатый и "виндам" с ним легче работать.

    Но этот способ работы с файлом который не находится в ресурсах программы (а это не всегда удобно)
    Поместить файл в ресурсы программы можно с помощью файла "rsrc.rc" и записи в нём:

    Код (Text):
    1. 2000  IMAGE  DISCARDABLE "a.gif"
    А вот как из ресурсов взять этот файл и сделать по этой же схеме из него хендл иконки у меня не получается.

    Можно конечно без проблем переконвертировать этот Gif в формат Ico и засунуть его в ресурсы.
    Таким образом работать с ним из ресурсов проблем не будет.
    Но так как размер формата Ico получается большой
    (потому что данные в нём не сжатые) поэтому не хотелось бы сильно раздувать экзешник.

    Крутил функцию:

    Код (Text):
    1. invoke BitmapFromResource, hInstance, 2000
    2. mov hBmp, eax
    Но нечего не получилось.
    Может я что то не так делаю?
    Не подскажете как правильно нужно вытащить из ресурсов этот файл и сделать из него хендл иконки.
     
  2. ASMatic

    ASMatic New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    233
  3. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Попробывал:

    invoke LoadImage,0,2000,IMAGE_BITMAP,0,0,000010h

    2000 - номер ресурса
    000010h - LR_LOADFROMFILE

    Возвращает ноль (ошибка)

    Что я делаю не правильно, подскажите пожалуйста.
     
  4. ASMatic

    ASMatic New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    233
    Код (Text):
    1.     hBitmap = LoadImage( hInstance,
    2.                          MAKEINTRESOURCE( IDB_BITMAP1 ),
    3.                          IMAGE_BITMAP,
    4.                          0,
    5.                          0,
    6.                          LR_DEFAULTCOLOR );
     
  5. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    MAKEINTRESOURCE( IDB_BITMAP1 )

    Не пойму что ставить мне во втором параметре

    Номер ресурса ? или что то ещё
    Честно говоря не могу разобратся
     
  6. ASMatic

    ASMatic New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    233
    ну неужели трудно пойти на мсдн где ВСЕ описано и почитать..
     
  7. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Мне конечно не трудно и я конечно был там и читал это
    Просто не пойму как на синтаксисе Асма поставить этот второй параметр
     
  8. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    ASMatic
    GIF изображение LoadImage не загрузит.

    assch
    Тут возможно как-то путем LoadResource загрузить GIF в память и работать с ним посредством GDI+.
     
  9. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    В принцыпи я написал алгоритм который это делает.
    Сначала методом парсинга функция ищет в своём же экзешнике
    этот загруженный файл. Потом копирует этот файл (как бы рядом с собой) Потом работает с этим файлом как было показано выше. Потом удаляет его.
    Этот метод работает вполне сносно.
    Я просто думал что найду другой способ.
    Попробую конечно ещё поковырять может что найду или кто нибудь подскажет.
    В любом случае всем спасибо за советы.
     
  10. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    assch
    Это кривой способ.
     
  11. kernel16

    kernel16 Human Vl

    Публикаций:
    0
    Регистрация:
    29 окт 2010
    Сообщения:
    316
    могу дать ещё кривее: :lol:
    вот GdipLoadImageFromFile использует CreatFile\ReadFile и т.п. их можно перехватить на время и вместо чтения файла просто выдавать куски, ранее подгруженные через LoadResource. :lol:
    ADD: только надо в 1м потоке выполняться, а то всякое может быть:lol:
     
  12. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Немного продвинулся в теме загрузки файлов изображений из ресурсов
    при помощи библиотеки GDI+
    Загружаешь файл в ресурсы.
    В файле "rsrc.rc" делаешь запись:

    Код (Text):
    1. 2001 GIF "a.gif"
    Инициализация:

    Код (Text):
    1. .data
    2. gifType    db "GIF", 0
    3.  
    4. .data?
    5. gifImage    dd ?
    6. hbuffer     dd ?
    7. pIStream    dd ?
    8. rcRes       dd ?
    9. hResData    dd ?
    10. sizeOfRes   dd ?
    11. hBitmap     dd ?
    12. hHeap       dd ?
    13. hIcon       dd ?
    14. Static      dd ?
    15. hIStream dd ?
    Код:

    Код (Text):
    1. invoke  FindResource, hInstance, 2001, addr gifType
    2. mov rcRes, eax
    3. invoke  LoadResource, hInstance, rcRes
    4. mov hResData, eax
    5. invoke  SizeofResource, hInstance, rcRes
    6. mov sizeOfRes, eax
    7. invoke  GetProcessHeap
    8. mov hHeap,eax
    9. invoke  HeapAlloc,hHeap,0,sizeOfRes
    10. mov hbuffer, eax
    11. invoke  RtlMoveMemory, hbuffer, hResData, sizeOfRes
    12. invoke  CreateStreamOnHGlobal, hbuffer, FALSE, addr pIStream
    13. invoke  GdipCreateBitmapFromStream, pIStream,addr  hBitmap
    Ну и дальше вывод изображения например как у меня было показано выше.

    Код (Text):
    1. invoke GdipCreateHICONFromBitmap,hBitmap,addr hIcon
    2. invoke SendMessage,Static,170h,hIcon,0
    3. invoke GdipDisposeImage,hBitmap
    Этот метод загрузки битмапа из потока работает вроде бы нормально
    со всеми популярными файлами (Jpg Gif Png Bmp).
    Только если захотите обьединить эти функции в одну функцию
    то переменные лучше сделать глобальные а то с локальными
    иногда будет работать не корректно.
    Вроде бы всё хорошо всё работает но не ндравится мне слишком
    большой набор функций для такой операции.
    Интересно что в GDI+ есть ещё одна функция

    GdipCreateBitmapFromResource

    описание функции:
    1 - Дескриптор экземпляра модуля.
    2 - Указатель на завершающуюся нулем Unicode строку, которая определяет
    путь и имя ресурса растрового изображения должны быть загружены.
    Кроме того, этот параметр может состоять из идентификатора ресурса
    в младшем слове и ноль в старшем слове.
    3 - Указатель на DWORD переменную, которая указатель на Bitmap объекта.

    По идее вроде бы должно работать так:

    Код (Text):
    1. invoke MultiByteToWideChar,0,0,addr gifType,-1,addr Unicod,addr Char
    2. invoke GdipCreateBitmapFromResource,hInstance,addr Unicod,addr hBitmap
    Но к сожелению не работает.
    И вместо "addr gifType" ставил просто "2001" всё равно
    функция не срабатывает и в переменной hBitmap чистый ноль.
    Честно говоря не пойму почему .
    Подозреваю что всё таки со вторым параметром у меня ошибка.

    В поиске нашёл один сайт где показаны как работают
    некоторые функции GDI+
    И в частности эта функция

    http://www.jose.it-berater.org/smfforum/index.php?topic=1800.0

    Там чисто показано что эта функция (всего одна) из ресурсов
    загружает битмам без проблем

    Не понятно.
    Может кто знает в чём проблемка.
     
  13. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    assch
    Вот это нормальный способ.
    Набор как набор, все тут нормально. Без всяких сохранений на диск.

    Наверно потому, что эта функция ожидает найти битмап в ресурсе (формат bmp).
     
  14. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    К сожелению загрузка файла Bmp тоже не чего не дала.
    Так что формат тут видно не причём.
    Да и для библиотеки GDI+ это было бы слишком не прилично.
    Она и создавалась для комфортной работы с этими форматами.
     
  15. ASMatic

    ASMatic New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    233
    K10
    тс спрашивал об иконке - а что там у него за расширения на иконках = хз.