原文:http://blogs.msdn.com/b/oldnewthing/archive/2010/10/18/10077133.aspx
(一)单色图标
这个礼拜我将花时间来说一下ICO文件格式的演化。首先图标资源的格式和图标文件的格式是不同的,这个我改日再说。
ICO文件有一个固定的文件头:
typedef struct ICONDIR {
WORD idReserved;
WORD idType;
WORD idCount;
ICONDIRENTRY idEntries[];
} ICONHEADER;
idReserved必须为0,idType必须为1。idCount表示这个图标里有多少个图像。ICO文件其实是由一组图像组成的。理论上来说,每个图像应该是同样的内容,但是不同的大小和颜色深度。当然,如果你要让一个16x16的图像和32x32的图像看起来完全不像,那也是可以的,不过用户可能会觉得很怪。
idCount之后是一个ICONDIRECTORY结构的数组。当然,数组的长度由idCount指定。
struct IconDirectoryEntry {
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInRes;
DWORD dwImageOffset;
};
bWidth和bHeight表示了图像的大小。一开始呢,只支持1到255的大小。从Windows95(NT 4.0)开始,用0来表示大小是256。
wBitCount和wPlanes用来描述图像的颜色深度。对单色图标来说,它们都为1。bReserved必须为0。dwBytesInRes和dwImageOffset用来描述实际图像数据的位置(相对于ICO文件的开始)和数据字节数。
然后,还有个悲剧的bColorCount。它被假定的认为等于图像的颜色数量,也就是说:
bColorCount = 1 << (wBitCount * wPlanes)
如果 wBitCount * wPlanes 大于等于8,则bColorCount为0。
在现实情况中,很多人懒得填写bColorCount的值,即使是4色或16色的图标,也把它设为0。从Windows XP开始,Windows会检测这个常见的错误,但是对于planar位图来说,这个自动纠错的机制还是有些问题的。幸运的是,几乎没人使用planar位图了。但是你还是不应该依赖于Windows提供的自动纠错机制,而正确的填写bColorCount的值。错误的bColorCount意味着,由于提供了错误的颜色深度信息,Windows可能会在ico文件中选择一个不怎么好的图像。