Russian Qt Forum

Компиляторы и платформы => Windows => Тема начата: OKTA от Сентябрь 09, 2014, 17:52



Название: [РЕШЕНО] Запилить иконку в exe
Отправлено: OKTA от Сентябрь 09, 2014, 17:52
Товарищи, пытаюсь засунуть иконку в exe-шник, но ничего не выходит. Ресурс пишется, но не полностью почему-то. Если у кого-то есть опыт, был бы рад услышать советы!


Название: Re: Запилить иконку в exe
Отправлено: kambala от Сентябрь 09, 2014, 20:33
зачем столько сложностей? http://qt-project.org/doc/qt-4.8/appicon.html


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 09:18
Мне надо уже в готовое приложение запиливать  :(


Название: Re: Запилить иконку в exe
Отправлено: Bepec от Сентябрь 10, 2014, 11:06
Как в готовое? В смысле стороннее приложение?


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 11:26
Да не обязательно стороннее, можно и мной скомпилированное. Так-то по факту, WinApi поволяет в любом exe-шнике менять, добавлять и удалять.


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 12:00
хм, с моим кодом работает?  ???
Не думаю, что косяк в правах, т.к. ресурс создается в целевом экзешнике - просто вместо данных картинки пишутся непонятные 6 байт непонятно чего. И это только в случае, если тип ресурса RT_GROUP_ICON. Если тип RT_ICON запись происходит нормально, но как я понял, нужен именно RT_GROUP_ICON.


Название: Re: Запилить иконку в exe
Отправлено: Bepec от Сентябрь 10, 2014, 12:08
Того, неправильное у меня сообщение было :) Я попытался установить иконку такую же, как и имеющаяся. Так что сорри.


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 12:09
 ;D ну вот, а я уже обрадовался  ;D


Название: Re: Запилить иконку в exe
Отправлено: Bepec от Сентябрь 10, 2014, 12:18
Судя по всему тут проблема в мааленьком уточнении в описании updateResource - все добавляемые ресурсы должны быть выровнены определённым образом.

Удаление ресурсов происходит нормально. Т.е. проблема всё же в картинке и/или image.

update: беглый поиск показал - iconGroup это группа иконок различных размеров. Попытка туда записать одну иконку окончится печально :D


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 12:39
Проверял - содержимое картинки один в один - в моем случае и в случае, если эта картинка устанавливается какой-нибудь утилиткой сторонней.
Очередной раз убеждаюсь, что WinApi - это полное недоразумение ..


Название: Re: Запилить иконку в exe
Отправлено: Bepec от Сентябрь 10, 2014, 12:42
Неа, всё правильно.

Посмотрите утилиту PEview  - она разложит по полочкам. GroupIcon это можно сказать указатели на иконки. Формата пока не нашёл, но там хранится 50-60 байт, указывающих количество/размеры иконок и их номера. А сами иконки должны быть загружены как иконки.

А вы туда херачите саму картинку.

PS WinApi страшная штука. Добавляем недокументированные возможности, запутанную документацию и ~ 50% устаревших функций :D

update а вот и структурка
Код:
#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
   WORD            idReserved;   // Reserved (must be 0)
   WORD            idType;       // Resource type (1 for icons)
   WORD            idCount;      // How many images?
   GRPICONDIRENTRY   idEntries[1]; // The entries for each image
} GRPICONDIR, *LPGRPICONDIR;
#pragma pack( pop )

The idCount member indicates how many images are present in the icon resource. The size of the idEntries array is determined by idCount. There exists one GRPICONDIRENTRY for each icon image in the resource, providing details about its size and color depth. The GRPICONDIRENTRY structure is defined as:
Код:
#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
   BYTE   bWidth;               // Width, in pixels, of the image
   BYTE   bHeight;              // Height, in pixels, of the image
   BYTE   bColorCount;          // Number of colors in image (0 if >=8bpp)
   BYTE   bReserved;            // Reserved
   WORD   wPlanes;              // Color Planes
   WORD   wBitCount;            // Bits per pixel
   DWORD   dwBytesInRes;         // how many bytes in this resource?
   WORD   nID;                  // the ID
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;
#pragma pack( pop )

The dwBytesInRes member indicates the total size of the RT_ICON resource referenced by the nID member. nID is the RT_ICON identifier that can be passed to FindResource, LoadResource and LockResource to obtain a pointer to the ICONIMAGE structure (defined above) for this image.
The following is an incomplete code fragment for reading icons from a .DLL or .EXE file:
Код:
// Load the DLL/EXE without executing its code
hLib = LoadLibraryEx( szFileName, NULL, LOAD_LIBRARY_AS_DATAFILE );
// Find the group resource which lists its images
hRsrc = FindResource( hLib, MAKEINTRESOURCE( nId ), RT_GROUP_ICON );
// Load and Lock to get a pointer to a GRPICONDIR
hGlobal = LoadResource( hLib, hRsrc );
lpGrpIconDir = LockResource( hGlobal );
// Using an ID from the group, Find, Load and Lock the RT_ICON
hRsrc = FindResource( hLib, MAKEINTRESOURCE( lpGrpIconDir->idEntries[0].nID ),
                      RT_ICON );
hGlobal = LoadResource( hLib, hRsrc );
lpIconImage = LockResource( hGlobal );
// Here, lpIconImage points to an ICONIMAGE structure


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 12:47
Да, до GroupIcon я тоже уже дошел, нашел что писать туда надо, но все равно пишутся те же дурацкие 6 байт вместо структуры с данными ;D


Название: Re: Запилить иконку в exe
Отправлено: Bepec от Сентябрь 10, 2014, 12:48
А где вы 6 байт видели? Я лично вижу в вашем примере ~72кб данных, что равно моей картинке :D


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 12:52
А я открываю exe-шник программулиной ResEdit и смотрю, что записано в ресурсах просто. А там 6 байт в поле данных валяется для GroupIcon :(


Название: Re: Запилить иконку в exe
Отправлено: Bepec от Сентябрь 10, 2014, 12:56
Мб ваша программулина рассчитана на работу с "фиксированным полем"? скачайте PEview. Очень рекомендую. Пусть и не очень навороченная, но помогает всегда.


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 13:07
Да, с PeView что-то начинает проясняться..
Спасибо, Верес! Как будут новости, дам знать!


Название: Re: Запилить иконку в exe
Отправлено: Bepec от Сентябрь 10, 2014, 13:13
Хочешь ещё немножко недокументированных структур?
(http://cs1492.vk.me/u13381622/a_4bffa380.jpg)

Получай.
Код:
struct ICONDIRENTRY {
    BYTE    bWidth;
    BYTE    bHeight;
    BYTE    bColorCount;
    BYTE    bReserved;
    WORD    wReserved1;
    WORD    wReserved2;
    DWORD    dwBytesInRes;
    DWORD    dwImageOffset;
};

struct ICONHEADER {
    WORD ihReserved;
    WORD ihType;
    WORD ihCount;
        
    ICONDIRENTRY *ihEntries;
};

struct ICONIMAGE {
    BITMAPINFOHEADER icHeader;
    RGBQUAD *icColors;
    BYTE *icXOR;
    BYTE *icAND;
};

struct ICON {
    ICONHEADER ich;
    ICONIMAGE *icm;
};

PS когда отчаешься отпишись, выделю время, тож покапаюсь :D


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 13:15
Ну где же она, ОС мечты...


Название: Re: Запилить иконку в exe
Отправлено: OKTA от Сентябрь 10, 2014, 14:11
Верес, ты получаешь приз зрительских симпатий  ;D

Все получилось - надо было только срезать первые 22 байта картинки  и правильно заполнить данные о картинке в GroupIcon  :D


Название: Re: Запилить иконку в exe
Отправлено: Bepec от Сентябрь 10, 2014, 14:25
(http://cs1492.vk.me/u13381622/a_4bffa380.jpg)
Всего то немного магии :)