Answer the question
In order to leave comments, you need to log in
How to solve the problem with writing a 256x256 icon to the *.exe file resources?
Greetings!
I set out to learn how to set an arbitrary icon for an arbitrary * .exe file. All this will be needed for the future project.
I write in Delphi, at the moment I completely switched to the XE5 version (before that, I used XE) for x64 and Android.
Operating system - Windows 8.1 Pro x64.
I immediately set myself the task of finding (making) code that compiles and is suitable for x32 and x64 executable files.
It was not possible to find anything suitable, although there were successful solutions. I decided to understand how it works (in what resources it is stored, what format these resources are available in) the *.exe icon in general.
I read carefully these two materials:
msdn.microsoft.com/en-us/library/ms997538.aspx
www.codeproject.com/Articles/30644/Replacing-ICON-...
I realized that in fact it is * .ico file. The difference with which is in two things:
1) The "entity" header is less than 2 bytes (for *.ico, the offset in the file is indicated - the DWORD type, and in the case of the application, the resource ID is indicated - the WORD type)
2) In the *.ico file, everything headers and data are included in 1 file and in application - headers are specified in RT_ICON_GROUP resource named 'MAINICON' and data is specified in RT_ICON resources with numeric name
Started writing code.
To begin with, I downloaded data from * .ico file and * .exe. Everything worked the first time, and worked without errors!
Further, I did the saving of the received data in * .ico - everything is fine. The icon file turned out to be identical in all checksums with the original one (including the one that was compiled into *.exe).
Here, at the stage of saving to *.exe, I immediately ran into a problem:
*.exe file was obtained without an icon, although all the resources were present in the water, but ResourceHacker could not read them.
All functions returned True.
I asked on several forums but couldn't find an answer.
I save like this:
procedure TdsIconResource.SaveToResource(aFileName: WideString; aLanguage: LANGID);
var
entityid: Word;
aStream: TMemoryStream;
hUpdate: THandle;
i: Integer;
entity: TdsIconResourceEntity;
procedure SpecialWrite(const Buffer; Count: Longint);
var
Writed: LongInt;
begin
Writed:=aStream.Write(Buffer, Count);
if Writed <> Count then
raise Exception.Create(Format('Writed fail, %d\%d', [writed, count]));
end;
begin
hUpdate:=BeginUpdateResourceW(PWideChar(aFileName), False);
aStream:=TMemoryStream.Create;
SpecialWrite(FHeader, SdsIconHeader);
for I := 0 to FHeader.wCount - 1 do
begin
entity:=TdsIconResourceEntity(FEntities.Objects[i]);
SpecialWrite(entity.FHeader, SdsIconEntityHeader);
entityid:=i+1;
SpecialWrite(entityid, SizeOf(Word));
entity.FData.Position:=0;
if not UpdateResourceW(hUpdate, RT_ICON, MAKEINTRESOURCE(entityid), aLanguage, entity.FData.Memory, entity.FData.Size) then
raise Exception.Create('not UpdateResourceW~Icon~, '+IntToStr(GetLastError));
end;
aStream.Position:=0;
if not UpdateResourceW(hUpdate, RT_GROUP_ICON, 'MAINICON', aLanguage, aStream.Memory, aStream.Size) then
raise Exception.Create('not UpdateResourceW~Group~, '+IntToStr(GetLastError));
if not EndUpdateResourceW(hUpdate, False) then
raise Exception.Create('not EndUpdateResourceW, '+IntToStr(GetLastError));
FreeAndNil(aStream);
end;
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question