您的位置:首页 > 其它

保存 EXE、DLL文件图标

2013-07-19 09:16 477 查看
//主函数为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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: