// 经我测试,8位色,15位色,24位色,32位色下都可以,就是16位色下,图形不正确
typedef struct tagICONDIRENTRY
{
BYTE bWidth; //图标宽度
BYTE bHeight; //图标高度
BYTE bColorCount; //图标颜色数
BYTE bReserved; //保留 为0
WORD wPlanes; //目标设备平面数,为1
WORD wBitCount; //图标中图像像素字节总数=
//位图信息+调色板+彩色位图位值+掩码位图位值
DWORD dwBytesInRes; //资源文件大小
DWORD dwImageOffset;//图标的图像像素离文件头的偏移量
} ICONDIRENTRY; //图标信息结构 typedef struct tagICONHEADER
{
WORD idReserved; //保留 为0
WORD idType; //图标文件类型 为1
WORD idCount; //该图标文件中保存的图标个数
} ICONHEADER; //图标文件头信息
void SaveIconFile(HDC h_DC,CString IconFileName,HICON *h_Icon,int IconCount)
{
ICONHEADER iconHeader;
iconHeader.idReserved = 0;
iconHeader.idType = 1;
iconHeader.idCount = IconCount; ICONDIRENTRY *idEntries=new ICONDIRENTRY[IconCount];
BYTE **iconAndCopy=new BYTE*[IconCount];
BYTE **iconXorCopy=new BYTE*[IconCount];
DWORD *sizeAnd =new DWORD[IconCount];
DWORD *sizeXor =new DWORD[IconCount];
BITMAPINFOHEADER* bmpHeader=new BITMAPINFOHEADER[IconCount];
RGBQUAD **rgbQuad=new RGBQUAD*[IconCount];
int *rgbNum=new int[IconCount];
for (int iconIndex=0;iconIndex<IconCount;iconIndex++)
{
//提取图标信息
ICONINFO iconInfo;
GetIconInfo(h_Icon[iconIndex],&iconInfo); //得到图标的彩色位图合掩码位图信息
CBitmap m_bitmap;
CBitmap* p_bitmapXor=m_bitmap.FromHandle(iconInfo.hbmColor);
CBitmap* p_bitmapAnd=m_bitmap.FromHandle(iconInfo.hbmMask);
BITMAP bitmapAnd,bitmapXor;
p_bitmapXor->GetBitmap(&bitmapXor);
p_bitmapAnd->GetBitmap(&bitmapAnd); //得到彩色位图和掩码位图的象素位值
sizeXor[iconIndex]=bitmapXor.bmHeight * bitmapXor.bmWidthBytes;
sizeAnd[iconIndex]=bitmapAnd.bmHeight * bitmapAnd.bmWidthBytes;
BYTE *iconXor=new BYTE[sizeXor[iconIndex]];
BYTE *iconAnd=new BYTE[sizeAnd[iconIndex]];
iconXorCopy[iconIndex]=new BYTE[sizeXor[iconIndex]];
iconAndCopy[iconIndex]=new BYTE[sizeAnd[iconIndex]];
p_bitmapXor->GetBitmapBits(sizeXor[iconIndex],iconXor);
p_bitmapAnd->GetBitmapBits(sizeAnd[iconIndex],iconAnd); //按行扫描倒置位图位值
for(int line=0;line<bitmapXor.bmHeight;line++)
for(int col=0;col<bitmapXor.bmWidthBytes;col++)
iconXorCopy[iconIndex][line*bitmapXor.bmWidthBytes+col]=
iconXor[(bitmapXor.bmHeight-line-1)*bitmapXor.bmWidthBytes+col]; for(int line=0;line<bitmapAnd.bmHeight;line++)
for(int col=0;col<bitmapAnd.bmWidthBytes;col++)
iconAndCopy[iconIndex][line*bitmapAnd.bmWidthBytes+col]=
iconAnd[(bitmapAnd.bmHeight-line-1)*bitmapAnd.bmWidthBytes+col]; //释放内存
if (iconXor) delete [] iconXor;
if (iconAnd) delete [] iconAnd; //设置位图信息
bmpHeader[iconIndex].biSize = sizeof(BITMAPINFOHEADER);
bmpHeader[iconIndex].biWidth = bitmapXor.bmWidth;
bmpHeader[iconIndex].biHeight = bitmapXor.bmHeight*2;
bmpHeader[iconIndex].biPlanes = bitmapXor.bmPlanes;
bmpHeader[iconIndex].biBitCount = bitmapXor.bmBitsPixel;
bmpHeader[iconIndex].biCompression = 0;
bmpHeader[iconIndex].biSizeImage = sizeXor[iconIndex];
bmpHeader[iconIndex].biXPelsPerMeter = 0;
bmpHeader[iconIndex].biYPelsPerMeter = 0;
bmpHeader[iconIndex].biClrUsed = 0;
bmpHeader[iconIndex].biClrImportant = 0; //获取颜色数
switch(bitmapXor.bmBitsPixel)
{
case 1: rgbNum[iconIndex]=1; break;
case 4: rgbNum[iconIndex]=16; break;
case 8: rgbNum[iconIndex]=256; break;
case 15: rgbNum[iconIndex]=32768; break;
case 16: rgbNum[iconIndex]=0;break;
case 32: rgbNum[iconIndex]=0;break;
default: rgbNum[iconIndex]=0;
} //得到系统调色板信息
PALETTEENTRY *palette=new PALETTEENTRY[rgbNum[iconIndex]];
GetSystemPaletteEntries(h_DC,0,rgbNum[iconIndex],palette);
//设置位图调色板信息
rgbQuad[iconIndex]=new RGBQUAD[rgbNum[iconIndex]];
for(int i=0;i<rgbNum[iconIndex];i++)
{
rgbQuad[iconIndex][i].rgbRed =palette[i].peRed;
rgbQuad[iconIndex][i].rgbGreen =palette[i].peGreen;
rgbQuad[iconIndex][i].rgbBlue =palette[i].peBlue;
rgbQuad[iconIndex][i].rgbReserved =palette[i].peFlags;
}
//释放系统调色板所占内存
if (palette) delete[] palette; //设置图标信息
idEntries[iconIndex].bWidth =(BYTE)bitmapXor.bmWidth ;
idEntries[iconIndex].bHeight=(BYTE)bitmapXor.bmHeight;
idEntries[iconIndex].bColorCount =(BYTE)bitmapXor.bmBitsPixel;
idEntries[iconIndex].bReserved = 0;
idEntries[iconIndex].wPlanes =bitmapXor.bmPlanes ;
idEntries[iconIndex].wBitCount = 0;
idEntries[iconIndex].dwBytesInRes =sizeof(BITMAPINFOHEADER)+rgbNum[iconIndex]*sizeof(RGBQUAD)+sizeXor[iconIndex]+sizeAnd[iconIndex];
if (iconIndex)
idEntries[iconIndex].dwImageOffset =
idEntries[iconIndex-1].dwImageOffset+
sizeof(BITMAPINFOHEADER)+
rgbNum[iconIndex-1]*sizeof(RGBQUAD)+
sizeXor[iconIndex-1]+sizeAnd[iconIndex];
else
idEntries[iconIndex].dwImageOffset =sizeof(ICONHEADER)+sizeof(ICONDIRENTRY)*IconCount;
} CFile file;
if(file.Open(IconFileName,CFile::modeCreate|CFile::modeWrite))
{
//写图标文件头
file.Write((void*)&iconHeader,sizeof(ICONHEADER));
//写图标目录
for(int iconIndex=0;iconIndex<IconCount;iconIndex++)
file.Write((void*)&idEntries[iconIndex],sizeof(ICONDIRENTRY)); for(int iconIndex=0;iconIndex<IconCount;iconIndex++)
{
//写图标位图信息
file.Write((void*)&bmpHeader[iconIndex],sizeof(BITMAPINFOHEADER));
//写位图调色板
file.Write((void*)rgbQuad[iconIndex],rgbNum[iconIndex]*sizeof(RGBQUAD));
//写彩色位图
file.Write(iconXorCopy[iconIndex],sizeXor[iconIndex]);
//写掩码位图
file.Write(iconAndCopy[iconIndex],128);//sizeAnd[iconIndex]);
} //关闭文件
file.Close();
}
//释放内存
for(int iconIndex=0;iconIndex<IconCount;iconIndex++)
{
if (rgbQuad[iconIndex]) delete [] rgbQuad[iconIndex];
if (iconXorCopy[iconIndex]) delete [] iconXorCopy[iconIndex];
if (iconAndCopy[iconIndex]) delete [] iconAndCopy[iconIndex];
}
if (bmpHeader) delete [] bmpHeader;
if (idEntries) delete [] idEntries;
if (sizeAnd) delete [] sizeAnd;
if (sizeXor) delete [] sizeXor;
if (iconAndCopy) delete [] iconAndCopy;
if (iconXorCopy) delete [] iconXorCopy;
if (rgbQuad) delete [] rgbQuad;
if (rgbNum) delete [] rgbNum;
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货