非API序列化ImageList_Write2和ImageList_Read2

来源:互联网 发布:newblue mac 编辑:程序博客网 时间:2024/06/05 06:31

ImageList是windows上一个比较重要的对象,可以方便的管理一串图标,其中ImageList_Write和ImageList_Read这两个API为我们提供了一个序列化ImageList的方法,但必须使用IStream接口来操作。在上次开发的一个工程中,因为使用了一个不同于IStream的二进制流类,为了使用该流进行ImageList的保存,我重新实现了自己的ImageList_Write2和ImageList_Read2.

下面贴出代码:

 

  1. BOOL HTImageListWrite2(HIMAGELIST img,CStream &s)
  2. {
  3.     INT dx,dy ;
  4.     IMAGEINFO imginf;
  5.     BITMAP bmp;
  6.     INT i;
  7.     WORD bitCount=32;
  8.     INT nTotalImages=ImageList_GetImageCount(img);
  9.     INT nValidImages=nTotalImages;
  10.     ImageList_GetIconSize(img,&dx,&dy);
  11.     s <<dx
  12.       <<dy
  13.       <<ImageList_GetBkColor(img);//background color
  14.     if(nTotalImages<=0){
  15.         s<<bitCount;
  16.     }else{      
  17.         ImageList_GetImageInfo(img,0,&imginf);
  18.         GetObject(imginf.hbmImage,sizeof(BITMAP),(LPSTR)&bmp);   
  19.         s<<bmp.bmBitsPixel;//颜色位数
  20.     }
  21.     s <<nTotalImages;
  22.     
  23.     if(nTotalImages<=0){
  24.         LOG0('E',"HTImageListWrite2","No valid iamges/r/n");
  25.         return TRUE;
  26.     }
  27.     HDC hdcDevice=GetDC(NULL);
  28.     DWORD dwImgPixelsInStreamOffset,dwImgBmpiInStreamOffset;
  29.     LPBYTE pImgPixelsInStream;
  30.     LPBITMAPINFOHEADER pImgBmpiInStream;
  31.     CreateBitmapStream(hdcDevice,imginf.hbmImage,dx,dy*nValidImages,s,
  32.         &dwImgBmpiInStreamOffset,&dwImgPixelsInStreamOffset);
  33.     DWORD dwMaskPixelsInStreamOffset,dwMaskBmpiInStreamOffset;
  34.     LPBYTE pMaskPixelsInStream;
  35.     LPBITMAPINFOHEADER pMaskBmpiInStream;
  36.     CreateBitmapStream(hdcDevice,imginf.hbmMask,dx,dy*nValidImages,s,
  37.         &dwMaskBmpiInStreamOffset,&dwMaskPixelsInStreamOffset);
  38.     pImgBmpiInStream=(LPBITMAPINFOHEADER)s.GetWritePoint(dwImgBmpiInStreamOffset);
  39.     pImgPixelsInStream=(LPBYTE)s.GetWritePoint(dwImgPixelsInStreamOffset);
  40.     pMaskBmpiInStream=(LPBITMAPINFOHEADER)s.GetWritePoint(dwMaskBmpiInStreamOffset);
  41.     pMaskPixelsInStream=(LPBYTE)s.GetWritePoint(dwMaskPixelsInStreamOffset);
  42.     INT byteImageWidth=pImgBmpiInStream->biSizeImage/pImgBmpiInStream->biHeight;
  43.     INT byteMaskWidth=pMaskBmpiInStream->biSizeImage/pMaskBmpiInStream->biHeight;
  44.     INT cy=0;
  45.     DWORD biImgSize=pImgBmpiInStream->biSizeImage;
  46.     DWORD biMaskSize=pMaskBmpiInStream->biSizeImage;
  47.     LONG biImgHeight=pImgBmpiInStream->biHeight;
  48.     LONG biMaskHeight=pMaskBmpiInStream->biHeight;
  49.     pImgBmpiInStream->biHeight=bmp.bmHeight;
  50.     pImgBmpiInStream->biSizeImage=byteImageWidth*bmp.bmHeight;
  51.     pMaskBmpiInStream->biHeight=bmp.bmHeight;
  52.     pMaskBmpiInStream->biSizeImage=byteMaskWidth*bmp.bmHeight;
  53.     for(i=nTotalImages-1;i>=0;i--)
  54.     {
  55.         ImageList_GetImageInfo(img,i,&imginf);
  56.         cy=imginf.rcImage.bottom-imginf.rcImage.top;
  57.         GetDIBits(hdcDevice,
  58.                 imginf.hbmImage,
  59.                 bmp.bmHeight-imginf.rcImage.bottom,
  60.                 cy,
  61.                 (LPSTR)pImgPixelsInStream,
  62.                 (LPBITMAPINFO)pImgBmpiInStream,
  63.                 DIB_RGB_COLORS);
  64.         pImgPixelsInStream+=byteImageWidth*cy;
  65.         GetDIBits(hdcDevice,
  66.                 imginf.hbmMask,
  67.                 bmp.bmHeight-imginf.rcImage.bottom,
  68.                 cy,
  69.                 (LPSTR)pMaskPixelsInStream,
  70.                 (LPBITMAPINFO)pMaskBmpiInStream,
  71.                 DIB_RGB_COLORS);
  72.             
  73.         pMaskPixelsInStream+=byteMaskWidth*cy;
  74.     }
  75.     
  76.     pImgBmpiInStream->biHeight=biImgHeight;
  77.     pImgBmpiInStream->biSizeImage=biImgSize;
  78.     pMaskBmpiInStream->biHeight=biMaskHeight;
  79.     pMaskBmpiInStream->biSizeImage=biMaskSize;
  80.     ::ReleaseDC(NULL,hdcDevice);
  81. #ifdef _TEST_
  82.     char sz[255];
  83.     sprintf(sz,"d://src%d.bmp",ttt++);
  84.     FILE *f=fopen(sz,"w+b");  
  85.     BITMAPFILEHEADER bf;
  86.     bf.bfType   =   0x4D42;   //   "BM"     
  87.     DWORD dwPaletteSize=0;
  88.     if(pImgBmpiInStream->biBitCount<=8)
  89.         dwPaletteSize=(1<<pImgBmpiInStream->biBitCount)*sizeof(RGBQUAD); 
  90.     DWORD dwDIBSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+pImgBmpiInStream->biSizeImage;       
  91.     bf.bfSize   =   dwDIBSize;     
  92.     bf.bfReserved1   =   0;
  93.     bf.bfReserved2   =   0;
  94.     bf.bfOffBits   =   (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)   +   dwPaletteSize;     
  95.      
  96.     fwrite((LPSTR)&bf,sizeof(BITMAPFILEHEADER),1,f);   //写入位图文件头      
  97.     fwrite(pImgBmpiInStream,sizeof(BITMAPINFOHEADER)+dwPaletteSize+pImgBmpiInStream->biSizeImage,1,f);   
  98.     fclose(f);
  99. #endif
  100.     return TRUE;
  101. }

 

 

下面是ImageList_Read2的代码:

 

  1. HIMAGELIST HTImageListRead2(HIMAGELIST img,CHTStream &s)
  2. {   
  3.     INT i;
  4.     INT dx,dy,nImages;
  5.     WORD bitCount=32;
  6.     INT flags=ILC_COLOR32;
  7.     COLORREF crBack;
  8.     s >>dx//图标尺寸
  9.       >>dy//图标尺寸
  10.       >>crBack//背景颜色
  11.       >>bitCount//颜色位数
  12.       >>nImages;//图像数目
  13.     switch(bitCount){
  14.     case 4: flags=ILC_COLOR4;break;
  15.     case 8: flags=ILC_COLOR8;break;
  16.     case 16: flags=ILC_COLOR16;break;
  17.     case 24: flags=ILC_COLOR24;break;
  18.     case 32: flags=ILC_COLOR32;break;
  19.     case 1:
  20.     case 2:
  21.     default:
  22.         flags=ILC_COLOR;
  23.         break;
  24.     }
  25.     if(NULL==img){
  26.         img=ImageList_Create(dx,dy,flags,0,4);
  27.     }
  28.     if(NULL==img){
  29.         return NULL;
  30.     }
  31.     ImageList_SetBkColor(img,crBack);
  32.     
  33.     if(nImages<=0){
  34.         return img;
  35.     }
  36.     //当前图像列表中已经存在的图像数目。
  37.     INT nTotalImages=ImageList_GetImageCount(img);
  38.     //载入图像数据
  39.     HDC hdcDevice=GetDC(NULL);
  40.     HDC hdcSrcImg=CreateCompatibleDC(hdcDevice);
  41.     HBITMAP hbmpSrcImg=LoadBitmapFromStream(s);//image
  42.     HGDIOBJ hbmpOldSrcImg=SelectObject(hdcSrcImg,hbmpSrcImg);
  43.     HDC hdcSrcMask=CreateCompatibleDC(hdcDevice);
  44.     HBITMAP hbmpSrcMask=LoadBitmapFromStream(s);//mask
  45.     HGDIOBJ hbmpOldSrcMask=SelectObject(hdcSrcMask,hbmpSrcMask);
  46.     HDC hdcDstImg=CreateCompatibleDC(hdcDevice);
  47.     HBITMAP hbmpDstImg=CreateCompatibleBitmap(hdcDevice,dx,dy);
  48.     HGDIOBJ hbmpOldDstImg;
  49.     HDC hdcDstMask=CreateCompatibleDC(hdcDevice);
  50.     HBITMAP hbmpDstMask=CreateCompatibleBitmap(hdcDevice,dx,dy);
  51.     HGDIOBJ hbmpOldDstMask;
  52.     {
  53.         for(i=0;i<nImages;i++)
  54.         {
  55.             hbmpOldDstImg=SelectObject(hdcDstImg,hbmpDstImg);
  56.             BitBlt(hdcDstImg,0,0,dx,dy,hdcSrcImg,0,i*dy,SRCCOPY);
  57.             SelectObject(hdcDstImg,hbmpOldDstImg);
  58.             
  59.             hbmpOldDstMask=SelectObject(hdcDstMask,hbmpDstMask);
  60.             BitBlt(hdcDstMask,0,0,dx,dy,hdcSrcMask,0,i*dy,SRCCOPY);     
  61.             SelectObject(hdcDstMask,hbmpOldDstMask);
  62.             
  63.             ImageList_Add(img,hbmpDstImg,hbmpDstMask);
  64.         }
  65.     }
  66.     SelectObject(hdcSrcMask,hbmpOldSrcMask);
  67.     DeleteDC(hdcSrcMask);
  68.     DeleteObject(hbmpSrcMask);
  69.     SelectObject(hdcSrcImg,hbmpOldSrcImg);
  70.     DeleteDC(hdcSrcImg);
  71.     DeleteObject(hbmpSrcImg);
  72.     DeleteDC(hdcDstMask);
  73.     DeleteObject(hbmpDstMask);
  74.     DeleteDC(hdcDstImg);
  75.     DeleteObject(hbmpDstImg);
  76.     ReleaseDC(NULL,hdcDevice);
  77.     if(arImages){
  78.         delete[] arImages;
  79.     }
  80.     return img;
  81. }