突然需要一个替换EXE文件图标的功能。网上找了几个例子,都是用程序中的资源来替换,却没有直接用硬盘上的ICO文件来替换的。
自己研究了一下ICO文件的保存格式后,写了一个方法。这里记下来,免得以后忘了……
BOOL ReplaceICO(LPCTSTR lpszApp, LPCTSTR lpszICO)
{
HANDLE hICO;
//打开硬盘上的图标文件
if (!(hICO = ::CreateFile(lpszICO, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)))
{
return FALSE;
}
LONG lOffset; //资源在文件中的偏移量
DWORD dwSize; //加载后资源的大小
DWORD dwReadByte; //读取文件时实际读取大小,API强制要求。其实没用……
LPVOID lpRes; //指向更新RT_ICON的资源
LPVOID lpGIco; //指向更新RT_GROUP_ICON的资源
CONST BYTE byGSize = 0x18; //RT_GROUP_ICON资源的大小,为常数。
//分配RT_GROUP_ICON资源的内存。
if (!(lpGIco = new BYTE[byGSize])) {::CloseHandle(hICO); return FALSE;}
memset(lpGIco, 0, byGSize);//清零RT_GROUP_ICON资源内存
::ReadFile(hICO, lpGIco, 0x06, &dwReadByte, NULL);//从文件中读取RT_GROUP_ICON资源头
::ReadFile(hICO, (LPVOID)((BYTE*)lpGIco + 0x08), 0x0C, &dwReadByte, NULL);//从文件中读取RT_GROUP_ICON资源
//获取ICO资源的大小。
memcpy((void*)&dwSize, (void*)((BYTE*)lpGIco + 0x10), sizeof(DWORD));
//获取ICO资源的偏移量。
::ReadFile(hICO, (void*)&lOffset, sizeof(LONG), &dwReadByte, NULL);
//分配ICO资源的内存。
if (!(lpRes = new BYTE[dwSize])) {delete[] lpGIco; ::CloseHandle(hICO); return FALSE;}
//偏移文件指针
::SetFilePointer(hICO, lOffset, NULL, FILE_BEGIN);
//读取图标资源到内存。
责任编辑:cyth