保存 EXE、DLL文件图标

来源:互联网 发布:数据库电子书 编辑:程序博客网 时间:2024/04/30 06:56

//主函数为SaveIco

/******************************************************************************/
// 宏定义
/******************************************************************************/
#define WIDTHBYTES(bits) ((((bits) + 31)>>5)<<2)


/******************************************************************************/
// 结构定义
/******************************************************************************/
#pragma pack( push )
#pragma pack( 2 )
typedef struct tagGRPICONDIRENTRY
{
    BYTE bWidth;
    BYTE bHeight;
    BYTE bColorCount;
    BYTE bReserved;
    WORD wPlanes;
    WORD wBitCount;
    DWORD dwBytesInRes;
    WORD nID;
}GRPICONDIRENTRY, *LPGRPICONDIRENTRY;;


typedef struct tagGRPICONDIR
{
    WORD idReserved;
    WORD idType;
    WORD idCount;
    GRPICONDIRENTRY idEntries[1];
}GRPICONDIR, *LPGRPICONDIR;
#pragma pack( pop )


typedef struct
{
UINT Width, Height, Colors; // Width, Height and bpp
LPBYTE lpBits;                // ptr to DIB bits
DWORD dwNumBytes;            // how many bytes?
LPBITMAPINFO lpbi;                  // ptr to header
LPBYTE lpXOR;                 // ptr to XOR image bits
LPBYTE lpAND;                 // ptr to AND image bits
} ICONIMAGE, *LPICONIMAGE;


typedef struct
{
UINT nNumImages;                      // How many images?
ICONIMAGE IconImages[1];                   // Image entries
} ICONRESOURCE, *LPICONRESOURCE;



//*****************************************************************************

// 得到颜色位数
//*****************************************************************************
WORD DIBNumColors(LPSTR lpbi)
{
  WORD wRet=0;
  WORD wBitCount;
  DWORD dwClrUsed;


  dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
  if(dwClrUsed) 
  {
    wRet = (WORD)dwClrUsed;
  }
  else
  {
    wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;


    switch(wBitCount)
{
      case 1:
wRet = 2;
break;


      case 4:
wRet = 16;
break;


      case 8:
wRet = 256;
break;


     default:
wRet = 0;
break;
    }
  }


  return wRet;
}


//*****************************************************************************
// 得到DIB数据地址
//*****************************************************************************
LPSTR FindDIBBits(LPSTR lpbi)
{
  WORD wPaletteSize;


  wPaletteSize = DIBNumColors(lpbi) * sizeof(RGBQUAD);


  return (lpbi + *(LPDWORD)lpbi + wPaletteSize);
}


//*****************************************************************************
// 每行字节数
//*****************************************************************************
DWORD BytesPerLine(LPBITMAPINFOHEADER lpBMIH)
{
  return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount);
}


//*****************************************************************************
//调整各项指针
//*****************************************************************************
BOOL AdjustIconImagePointers(LPICONIMAGE lpImage)
{
  // Sanity check
  if(lpImage == NULL)   return FALSE;


  // BITMAPINFO is at beginning of bits
  lpImage->lpbi = (LPBITMAPINFO)lpImage->lpBits;
  // Width - simple enough
  lpImage->Width = lpImage->lpbi->bmiHeader.biWidth;
  // Icons are stored in funky format where height is doubled - account for it
  lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight)/2;
  // How many colors?
  lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes * lpImage->lpbi->bmiHeader.biBitCount;


  // XOR bits follow the header and color table
  lpImage->lpXOR = (LPBYTE)FindDIBBits((LPSTR)lpImage->lpbi);


  // AND bits follow the XOR bits
  lpImage->lpAND = lpImage->lpXOR + (lpImage->Height*BytesPerLine((LPBITMAPINFOHEADER)(lpImage->lpbi)));


  return TRUE;
}


//*****************************************************************************
//计算ICON图标数据偏移地址
//*****************************************************************************
DWORD CalculateImageOffset(LPICONRESOURCE lpIR, UINT nIndex)
{
  DWORD dwSize;
  UINT  i;


  dwSize = 3 * sizeof(WORD);
  dwSize += lpIR->nNumImages * sizeof(ICONDIRENTRY);
  for(i=0; i<nIndex; i++)  dwSize += lpIR->IconImages[i].dwNumBytes;
  
  return dwSize;
}


//*****************************************************************************
//保存ICON文件头
//*****************************************************************************
BOOL WriteICOHeader(HANDLE hFile, UINT nNumEntries)
{
  WORD  Output;
  DWORD dwBytesWritten;
  
  Output = 0;
  if(!WriteFile(hFile, &Output, sizeof(WORD), &dwBytesWritten, NULL))  return FALSE;
  if(dwBytesWritten != sizeof(WORD)) return FALSE;


  Output = 1;
  if(!WriteFile(hFile, &Output, sizeof(WORD), &dwBytesWritten, NULL))  return FALSE;
  if(dwBytesWritten != sizeof(WORD))  return FALSE;


  Output = (WORD)nNumEntries;
  if(!WriteFile(hFile, &Output, sizeof(WORD), &dwBytesWritten, NULL))  return FALSE;
  if(dwBytesWritten != sizeof(WORD))  return FALSE;


  return TRUE;
}


//*****************************************************************************
// 保存ICON图标
// lpszApp:    包含图标资源的EXE、DLL文件
// lpszName:   图标资源名称或ID
// szFilePath: 图标文件名
//*****************************************************************************
BOOL SaveIcon(LPCTSTR lpszApp, LPTSTR lpszName, LPCTSTR szFilePath)

  BOOL    fgRet = FALSE; 
  DWORD   dwSize;
  LPTSTR  lpName; 
  
  HINSTANCE      hLibrary;     
  HRSRC          hResSrc(NULL);    
  HGLOBAL        hGlobal(NULL);  
  LPGRPICONDIR   lpResGroup(NULL) ;
  LPVOID  lpResIcon(NULL);
  LPICONRESOURCE lpIR(NULL);


  DWORD dwId = (DWORD)lpszName;
  if(HIWORD(dwId) == 0)
  {
lpName = MAKEINTRESOURCE(dwId);
  }
  else
  {
    dwId = *((DWORD *)lpszName);
    if(HIWORD(dwId) == 0)
      lpName = MAKEINTRESOURCE(dwId);
    else
 lpName = lpszName;
  }


  //装入EXE文件,并读取资源  
  hLibrary = ::LoadLibrary(lpszApp);                                //装载模块
  if(hLibrary == NULL) return FALSE;  
  hResSrc = ::FindResource(hLibrary, lpName, RT_GROUP_ICON);        //查找指定资源
  if(hResSrc == NULL)  {::FreeLibrary(hLibrary); return FALSE;}
  hGlobal = LoadResource(hLibrary, hResSrc);                        //装载找到的资源
  if(hGlobal == NULL)  {::FreeLibrary(hLibrary); return FALSE;}
  lpResGroup = (LPGRPICONDIR)LockResource(hGlobal);                 //锁定资源
  if(lpResGroup == NULL)   {::FreeLibrary(hLibrary); return FALSE;}


  //为资源分配内存空间
  lpIR = (LPICONRESOURCE)malloc(sizeof(ICONRESOURCE) + ((lpResGroup->idCount-1)*sizeof(ICONIMAGE)));
  if(lpIR == NULL)   {::FreeLibrary(hLibrary); return FALSE;}
  
  //保存图标数据
  lpIR->nNumImages = lpResGroup->idCount;
  for(UINT i=0; i<lpResGroup->idCount; i++)
  {
    //查找并定位图标资源
    hResSrc = FindResource(hLibrary, MAKEINTRESOURCE(lpResGroup->idEntries[i].nID), RT_ICON);
    if(hResSrc == NULL)   {::FreeLibrary(hLibrary); return FALSE;}
hGlobal = LoadResource(hLibrary, hResSrc);
if(hGlobal == NULL)   {::FreeLibrary(hLibrary); return FALSE;}
lpResIcon = LockResource(hGlobal); 
    if(lpResIcon == NULL) {::FreeLibrary(hLibrary); return FALSE;}


//资源大小 
dwSize = SizeofResource(hLibrary, hResSrc);     


//填充图标数据各各项指针
    lpIR->IconImages[i].dwNumBytes = dwSize;
    lpIR->IconImages[i].lpBits = (LPBYTE)malloc(dwSize);
    memcpy(lpIR->IconImages[i].lpBits, lpResIcon, dwSize);
    AdjustIconImagePointers(&(lpIR->IconImages[i]));    
  }


  //释放资源
  ::FreeLibrary(hLibrary);


  //保存数据为文件
  HANDLE hFile;
  hFile = CreateFile(szFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if(hFile== INVALID_HANDLE_VALUE)  return FALSE;
  
  //写文件头
  if(!WriteICOHeader(hFile, lpIR->nNumImages))   
  {
CloseHandle( hFile );
return FALSE; 
  }    
 
  //写文件描述信息
  ICONDIRENTRY ide;
  for(i=0; i<lpIR->nNumImages; i++)
  {
     ide.bWidth = lpIR->IconImages[i].Width;
     ide.bHeight = lpIR->IconImages[i].Height;
     ide.bReserved = 0;
     ide.wPlanes = lpIR->IconImages[i].lpbi->bmiHeader.biPlanes;
     ide.wBitCount = lpIR->IconImages[i].lpbi->bmiHeader.biBitCount;
     if((ide.wPlanes * ide.wBitCount) >= 8)
       ide.bColorCount = 0;
     else
       ide.bColorCount = 1 << (ide.wPlanes * ide.wBitCount);
     ide.dwBytesInRes = lpIR->IconImages[i].dwNumBytes;
     ide.dwImageOffset = CalculateImageOffset(lpIR, i);


     if(!WriteFile(hFile, &ide, sizeof(ICONDIRENTRY), &dwSize, NULL)) return FALSE;
     if(dwSize != sizeof(ICONDIRENTRY))  return FALSE;
  }


  //写图像数据
  for(i=0; i<lpIR->nNumImages; i++ )
  {
     DWORD dwTemp = lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage;


     lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = 0;


     if(!WriteFile(hFile, lpIR->IconImages[i].lpBits, lpIR->IconImages[i].dwNumBytes, &dwSize, NULL)) return FALSE;
     if(dwSize != lpIR->IconImages[i].dwNumBytes)  return FALSE;
        
     lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = dwTemp;
  }


  CloseHandle( hFile );


  return fgRet; 
}
原创粉丝点击