Создать RES-файл иконки без сторонних утилит

Тема в разделе "WASM.WIN32", создана пользователем DevilDevil, 6 апр 2009.

  1. DevilDevil

    DevilDevil Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2007
    Сообщения:
    101
    Здравствуйте.
    Будет здорово, если кто-то поможет, если хорошо знаком с форматом RES-файлов.

    Задача проста.
    Есть *.ico-файл, необходимо создать res файл, в котором будет эта иконка. Имя ресурса - любое. Тип - RT_ICON.
     
  2. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    почитай макросы от фасма
     
  3. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    проще прочитать msdn
     
  4. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Ресурс компайлер не сторонняя утилита. Она - родная, от Майкрософта.
     
  5. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Курить нужно http://msdn.microsoft.com/en-us/library/ms648007.aspx и, в частности, описание RESOURCEHEADER (там ссылка есть).
    Для иконок нужен не только ресурс RT_ICON, но и RT_GROUP_ICON.
    Код на макросах fasm, учитывает, что в .ico файлах бывает несколько иконок с разными разрешениями (ресурс будет один):
    Код (Text):
    1. iconfile equ '1.ico'
    2. iconid equ 101
    3.  
    4.     dd  0, 20h
    5.     dw  0xFFFF, 0
    6.     dw  0xFFFF, 0
    7.     dd  0, 0, 0, 0
    8.  
    9. virtual at 0
    10. ; load .ico header
    11. file iconfile:0,6
    12. load idReserved word from 0
    13. load idType word from 2
    14. load idCount word from 4
    15. if (idReserved <> 0) | (idType <> 1)
    16. error invalid icon file
    17. end if
    18. end virtual
    19.  
    20. repeat idCount
    21. virtual at 0
    22. file iconfile:6+16*(%-1)+8,8
    23. load dwBytesInRes dword from 0
    24. load dwImageOffset dword from 4
    25. end virtual
    26.     dd  dwBytesInRes, 20h
    27.     dw  0xFFFF, 3   ; RT_ICON
    28.     dw  0xFFFF, %
    29.     dd  0
    30.     dw  1030h
    31.     dw  0
    32.     dd  0
    33.     dd  0
    34. file iconfile:dwImageOffset,dwBytesInRes
    35. while dwBytesInRes and 3
    36. dwBytesInRes = dwBytesInRes + 1
    37.     db  0
    38. end while
    39. end repeat
    40.  
    41.     dd  6 + 14*idCount, 20h
    42.     dw  0xFFFF, 14  ; RT_GROUP_ICON
    43.     dw  0xFFFF, iconid
    44.     dd  0
    45.     dw  1030h
    46.     dw  0
    47.     dd  0
    48.     dd  0
    49. ; RT_GROUP_ICON data
    50.     dw  0, 1, idCount   ; idCount images
    51. repeat idCount
    52.     file    iconfile:6+16*(%-1),12
    53.     dw  %
    54. end repeat
    55. while $ and 3
    56.     db  0
    57. end while
    Added: забыл сразу написать - иконка будет экспортироваться по идентификатору iconid (в коде он 101, естественно, можно заменить на свой); для экспорта по имени нужно соответственно изменить RESOURCEHEADER для RT_GROUP_ICON.
     
  6. DevilDevil

    DevilDevil Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2007
    Сообщения:
    101
    diamond,

    спасибо. Прошу прощения, а на Си это как выглядит (хотя бы в псевдокоде) ?
     
  7. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Вообще-то приходить на изначально ассемблерный форум и просить переписать код на Си - это наглость...
    А что непонятного? db/dw/dd? Директива file <filename>:<offset>,<length> загружает <length> байт из файла со смещения <offset>, приколы с virtual и load имеют смысл загрузки нужных значений из файла в переменные.
     
  8. DevilDevil

    DevilDevil Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2007
    Сообщения:
    101
    Есть RESOURCEHEADER. Если тип/имя - число, то можно использовать тип
    struct RESOURCEHEADER {
    DWORD DataSize;
    DWORD HeaderSize; // = sizeof(RESOURCEHEADER) = 32
    DWORD TYPE; // 0xFFFF | (Type << 16)
    DWORD NAME; // 0xFFFF | (Name << 16)
    DWORD DataVersion;
    WORD MemoryFlags; // = 0x1030
    WORD LanguageId;
    DWORD Version;
    DWORD Characteristics;
    };

    В ресурсном файле сначала идёт пустой RESOURCEHEADER, а потом RESOURCEHEADER для каждого ресурса.

    Собственно, непонятно:
    1) сколько RESOURCEHEADER-секций создаётся для одного *.ico файла
    2) причём тут RT_GROUP_ICON
    3) какая(ие) часть(и) *.ico файла пишутся как Data
    4) какие данные заголовка иконки берутся
    5) какие заголовки кроме RESOURCEHEADER, используются для иконки
     
  9. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    тебе дали макрос. что в нем не понятного. там все это есть.
    virtual at 0 говорит о том, что сгенерированный код будет располагаться в позиции 0 логического пространства, но в файл помещен не будет
    file iconfile:0,6 читает со смещения 0 из iconfile 6 байт и помещает их в этот блок

    load idReserved word from 0 берет по смещению 0 в логическом блоке 2 байта и помещает значение в переменную idReserved
    load idType word from 2 берет по смещению 2 в логическом блоке 2 байта и помещает значение в переменную idType
    load idCount word from 4 берет по смещению 4 в логическом блоке 2 байта и помещает значение в переменную idCount

    end virtual закрываем эту конструкцию. код пропадает, а значения переменных idReserved, idType и idCount остаются (чудом избегают уничтожения!)

    остальное очень похоже на СИ. Ах да. Вместо переменной счетчиком цикла, начинающим отсчет с 1, в конструкции repeat <count>/end repeat выступает %
    ADD: И еще чуть не забыл. $ - текущая позиция в уже сгенерированном файле (оффсет). dq=double, dd = unsigned int/int/float (по вкусу), dw = unsigned short int/short int (по вкусу), а db = unsigned char/char/bool (по вкусу)
    в результате автозамены получаем
    Код (Text):
    1. iconfile equ '1.ico'
    2. iconid equ 101
    3.  
    4.     int __a=0, __b=20h
    5.     short int   __c=0xFFFF, __d=0
    6.     int __e=0xFFFF, __f=0
    7.     short int   __g=0, __h=0, __i=0, __j=0
    8.  
    9. virtual at 0
    10. ; load .ico header
    11. file iconfile:0,6
    12. load idReserved word from 0
    13. load idType word from 2
    14. load idCount word from 4
    15. if (idReserved <> 0) | (idType <> 1)
    16. error invalid icon file
    17. end if
    18. end virtual
    19.  
    20. for (int i=1; i<=idCount; i++)
    21. {
    22. virtual at 0
    23. file iconfile:6+16*(i-1)+8,8
    24. load dwBytesInRes dword from 0
    25. load dwImageOffset dword from 4
    26. end virtual
    27.     int _a=dwBytesInRes, ___b=20h
    28.     short int   _b=0xFFFF, ___c=3   ; RT_ICON
    29.     short int   _c=0xFFFF, ___d=i
    30.     int _d=0
    31.     short int   _e=1030h
    32.     short int   _f=0
    33.     int _g=0
    34.     int _h=0
    35. file iconfile:dwImageOffset,dwBytesInRes
    36.        char xx[dwBytesInRes and 3]=(0,...,0);
    37. }
    38.  
    39.     int a=6 + 14*idCount, 20h
    40.     short int   b=0xFFFF, 14    ; RT_GROUP_ICON
    41.     short int   c=0xFFFF, iconid
    42.     int d=0
    43.     short int   e=1030h
    44.     short int   f=0
    45.     int g=0
    46.     int h=0
    47. ; RT_GROUP_ICON data
    48.     short int idCount[3]=(0, 1, idCount)    ; idCount images
    49. short int xxx[idCount]
    50. for (int i=1; i<=idCount; i++)
    51. {
    52.     file    iconfile:6+16*(i-1),12
    53.     xxx[i-1]=i
    54. }
    55. while $ and 3
    56.     db  0
    57. end while
    ADD: а. кое-что забыл поменять.
     
  10. DevilDevil

    DevilDevil Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2007
    Сообщения:
    101
    ВСЕМ ОГРОМНОЕ СПАСИБО !!!

    P.S. Намудрили они что-то с форматом иконок
     
  11. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.785