I\'m just wondering, if there an API in Windows for loading the HICON
from the byte array (buffer)? Let\'s say that I downloaded an *.ico
file and
I found a solution. Actually after a bit of research it turned out that the code, which I placed inside the sample, is indeed correct.
There is a bug in WinAPI function LookupIconIdFromDirectoryEx()
. I've noticed that for some icons I can get the correct icon and set it up, but for others it fails either on the later stage CreateIconFromResourceEx()
, or earlier on LookupIconIdFromDirectoryEx()
. I've noticed that sometimes the function fails to find the icon even though the icon is inside a file. Sometimes the function returned the same value for the different icons inside an icon file.
I made several rounds of tests and parsed the format of each icon file myself based on the format definition. Then I compared the actual offsets to the values returned by LookupIconIdFromDirectoryEx()
.
Let's say we have 2 icons: A
and B
.
The A
icon in my case contained 5 images, the entries inside the ICO file were placed in the following order:
The B
icon contained 7 images, they were placed in the following order:
The results of the LookupIconIdFromDirectoryEx()
for each of the icons can be found below.
Icon A
:
Icon B
:
0
)0
)0
)I parsed the actual format, according to the definition in wikipedia (the tables below are contain the icon entries, each row is a separate entry, each column is a field for this entry) for both icon files.
The actual layout of A
is:
W H * * * ** SIZE OFFSET
------------------------------------------------
0 0 0 0 1 32 43253 86
128 128 0 0 1 32 67624 43339
48 48 0 0 1 32 9640 110963
32 32 0 0 1 32 4264 120603
16 16 0 0 1 32 1128 124867
The actual layout of B
is:
W H * * * ** SIZE OFFSET
------------------------------------------------
16 16 0 0 0 32 1128 102
32 32 0 0 0 32 4264 1230
48 48 0 0 0 32 9640 5494
64 64 0 0 0 32 16936 15134
128 128 0 0 0 32 67624 32070
0 0 0 0 0 32 270376 99694
So you can clearly see, that in case of A
only the offset for the first image was idenfied correct, offsets for other images were incorrect and equal to the ... size of the 3rd image (??), maybe just a coincidence.
In case of the second image all offsets were correct until we reached 128x128 image, which was not even found.
The common thing between those 2 cases is that the function started to behave strange after parsing 128x128 icon, and here is an interesting thing - look on the size of 128x128 icon and compare it to the size of the other images. In both cases the size of the 128x128 image does not fit in 2 bytes. Right after parsing the icon entry in which the size was bigger than 2 bytes, the function behavior is undefined. Judging from this data I can assume that somewhere in the code they expect that the size of the icon cannot be bigger than 2 bytes. In case if the size is bigger, the behavior is undefined.
I used ImageMagick to reassemble a new icon which does not have such image inside and now the function works correct in all cases.
So I can definitely say that there is a bug inside LookupIconIdFromDirectoryEx()
implementation.
UPD. Icons can be found here: A icon, B icon.