如何将一个图标资源存为一个图标文件(.ico)? 在Visual Studio中的ResourceView中选中需导出的图标资源,点击右键弹出菜单,选择Export......即可。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 IconNum = ExtractIconEx(IconFile,-1,IconLarge,IconSmall,0);得到IconFile中图标个数ExtractIconEx(IconFile,IconIndex,IconLarge,IconSmall,IconNum);IconLarge和IconSmall分别得到大小图标句柄 Asima, 得到句柄后又该怎办? 我也是最近在写一个程序用到这个东西下边是我的代码注意:现在还有一个问题就是当系统色彩设置为16位色(不是16色)时,保存的图标就有问题,问题的原因是这样的:我的代码中通过图标句柄得到的图标信息iconInfo然后通过iconInfo.hbmColor得到位图,这时位图色彩为16位色图标中不支持这么高的色彩我现在不知怎样才能得到低于系统色彩设置的位图所以我把系统色彩设置为256色,经过测试这种情况下没有问题注意调用该函数时应传递一个CDC的参数,可以将窗体的客户区DC传给它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=2);void SaveIconFile(HDC h_DC,CString IconSFile,CString IconDFile);void SaveIconFile(HDC h_DC,CString IconSFile,CString IconDFile){ HICON h_Icon[2]; //得到文件中的图标个数 int IconCount = ExtractIconEx(IconSFile,-1,NULL,NULL,0); for(int iconIndex=0;iconIndex<IconCount;iconIndex++) { ExtractIconEx(IconSFile,iconIndex,h_Icon,h_Icon+1,IconCount); CString IconFileName; IconFileName.Format("%d",iconIndex); IconFileName=IconDFile+IconFileName+".ico"; if(h_Icon[0] && h_Icon[1]) SaveIconFile(h_DC,IconFileName,h_Icon); else if(h_Icon[0]) SaveIconFile(h_DC,IconFileName,h_Icon,1); else if(h_Icon[1]) SaveIconFile(h_DC,IconFileName,h_Icon+1,1); }}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(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 16: rgbNum[iconIndex]=65536;break; default: rgbNum[iconIndex]=16; } //得到系统调色板信息 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 and CFile::modeWrite)) { //写图标文件头 file.Write((void*)&iconHeader,sizeof(ICONHEADER)); //写图标目录 for(iconIndex=0;iconIndex<IconCount;iconIndex++) file.Write((void*)&idEntries[iconIndex],sizeof(ICONDIRENTRY)); for(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(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;} ADO访问技术 如何用ATL写一个excel 2003的插件? 我想实现一个对话框~对折的效果该怎么办? 密码 关于.CHM格式问题。 hook的问题 高手告诉我吧,两个文本文件怎么比较. 对话框应用程序中怎样加入数据库的支持 获得函数 地址 需要用 取地址符号吗? 关于一个API函数GetSaveFileName 各位高手帮帮忙 自动化组件的困惑
得到IconFile中图标个数
ExtractIconEx(IconFile,IconIndex,IconLarge,IconSmall,IconNum);
IconLarge和IconSmall分别得到大小图标句柄
得到句柄后又该怎办?
下边是我的代码
注意:现在还有一个问题就是当系统色彩设置为16位色(不是16色)时,保存的图标就有问题,问题的原因是这样的:
我的代码中通过图标句柄得到的图标信息iconInfo
然后通过iconInfo.hbmColor得到位图,这时位图色彩为16位色
图标中不支持这么高的色彩
我现在不知怎样才能得到低于系统色彩设置的位图
所以我把系统色彩设置为256色,经过测试这种情况下没有问题
注意调用该函数时应传递一个CDC的参数,可以将窗体的客户区DC传给它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=2);
void SaveIconFile(HDC h_DC,CString IconSFile,CString IconDFile);void SaveIconFile(HDC h_DC,CString IconSFile,CString IconDFile)
{
HICON h_Icon[2];
//得到文件中的图标个数
int IconCount = ExtractIconEx(IconSFile,-1,NULL,NULL,0);
for(int iconIndex=0;iconIndex<IconCount;iconIndex++)
{
ExtractIconEx(IconSFile,iconIndex,h_Icon,h_Icon+1,IconCount);
CString IconFileName;
IconFileName.Format("%d",iconIndex);
IconFileName=IconDFile+IconFileName+".ico";
if(h_Icon[0] && h_Icon[1])
SaveIconFile(h_DC,IconFileName,h_Icon);
else if(h_Icon[0])
SaveIconFile(h_DC,IconFileName,h_Icon,1);
else if(h_Icon[1])
SaveIconFile(h_DC,IconFileName,h_Icon+1,1);
}
}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(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 16: rgbNum[iconIndex]=65536;break;
default: rgbNum[iconIndex]=16;
}
//得到系统调色板信息
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 and CFile::modeWrite))
{
//写图标文件头
file.Write((void*)&iconHeader,sizeof(ICONHEADER));
//写图标目录
for(iconIndex=0;iconIndex<IconCount;iconIndex++)
file.Write((void*)&idEntries[iconIndex],sizeof(ICONDIRENTRY));
for(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(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;
}