在Visual Studio中的ResourceView中选中需导出的图标资源,点击右键弹出菜单,选择Export......即可。

解决方案 »

  1.   

    IconNum = ExtractIconEx(IconFile,-1,IconLarge,IconSmall,0);
    得到IconFile中图标个数
    ExtractIconEx(IconFile,IconIndex,IconLarge,IconSmall,IconNum);
    IconLarge和IconSmall分别得到大小图标句柄    
      

  2.   

    Asima,
      得到句柄后又该怎办?
      

  3.   

    我也是最近在写一个程序用到这个东西
    下边是我的代码
    注意:现在还有一个问题就是当系统色彩设置为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;
    }