UpdateResource 替换图标有问题,第一个图标无法替换或者为空

xcfdsarfew 2019-03-23 03:22:32


#pragma once
typedef struct tagHEADER
{
WORD idReserved;
WORD idType;
WORD idCount;
}HEADER, *LPHEADER;

typedef struct tagICONDIRENTRY
{
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInRes;
DWORD dwImageOffset;
}ICONDIRENTRY, *LPICONDIRENTRY;

#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 )






#include "Windows.h"
#include <iostream>
#include <atlstr.h>
#include "IconReplace.h"

using namespace std;

void changedExeIcon(CString lpExeName, CString lpIconFile)
{
LPICONDIRENTRY pIconDirEntry(NULL);
LPGRPICONDIR pGrpIconDir(NULL);
HEADER header;
LPBYTE pIconBytes(NULL);
HANDLE hIconFile(NULL);
DWORD dwRet(0), nSize(0), nGSize(0), dwReserved(0);
HANDLE hUpdate(NULL);
BOOL ret(FALSE);
WORD i(0);

//打开图标文件
hIconFile = CreateFile(lpIconFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hIconFile == INVALID_HANDLE_VALUE)
{
return;
}
//读取文件头部信息
ret = ReadFile(hIconFile, &header, sizeof(HEADER), &dwReserved, NULL);
if (!ret)
{
CloseHandle(hIconFile);
return;
}
//建立每一个图标的目录信息存放区域
pIconDirEntry = (LPICONDIRENTRY)new BYTE[header.idCount * sizeof(ICONDIRENTRY)];
if (pIconDirEntry == NULL)
{
CloseHandle(hIconFile);
return;
}
//从Icon文件中读取每一个图标的目录信息
ret = ReadFile(hIconFile, pIconDirEntry, header.idCount * sizeof(ICONDIRENTRY), &dwReserved, NULL);
if (!ret)
{
delete[] pIconDirEntry;
CloseHandle(hIconFile);
return;
}
//建立EXE文件中RT_GROUP_ICON所需的数据结构存放区域
nGSize = sizeof(GRPICONDIR) + header.idCount * sizeof(ICONDIRENTRY);
pGrpIconDir = (LPGRPICONDIR)new BYTE[nGSize];
//填充信息,这里相当于一个转换的过程
pGrpIconDir->idReserved = header.idReserved;
pGrpIconDir->idType = header.idType;
pGrpIconDir->idCount = header.idCount;
//复制信息并设置每一个图标对应的ID。ID为位置索引号
for (i = 0; i < header.idCount; i++)
{
pGrpIconDir->idEntries[i].bWidth = pIconDirEntry[i].bWidth;
pGrpIconDir->idEntries[i].bHeight = pIconDirEntry[i].bHeight;
pGrpIconDir->idEntries[i].bColorCount = pIconDirEntry[i].bColorCount;
pGrpIconDir->idEntries[i].bReserved = pIconDirEntry[i].bReserved;
pGrpIconDir->idEntries[i].wPlanes = pIconDirEntry[i].wPlanes;
pGrpIconDir->idEntries[i].wBitCount = pIconDirEntry[i].wBitCount;
pGrpIconDir->idEntries[i].dwBytesInRes = pIconDirEntry[i].dwBytesInRes;
pGrpIconDir->idEntries[i].nID = i;
}
//开始更新EXE中的图标资源,ID定为最小0,如果原来存在0ID的图标信息则被替换为新的。
hUpdate = BeginUpdateResource(lpExeName, false);
if (hUpdate != NULL)
{
//首先更新RT_GROUP_ICON信息
ret = UpdateResource(hUpdate, RT_GROUP_ICON, MAKEINTRESOURCE(128), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), (LPVOID)pGrpIconDir, nGSize);
if (!ret)
{
delete[] pIconDirEntry;
delete[] pGrpIconDir;
CloseHandle(hIconFile);
return;
}
//接着的是每一个Icon的信息存放
for (i = 0; i < header.idCount; i++)
{
//Icon的字节数
nSize = pIconDirEntry[i].dwBytesInRes;
//偏移文件的指针到当前图标的开始处
dwRet = SetFilePointer(hIconFile, pIconDirEntry[i].dwImageOffset, NULL, FILE_BEGIN);
if (dwRet == INVALID_SET_FILE_POINTER)
{
break;
}
//准备pIconBytes来存放文件里的Byte信息用于更新到EXE中。
delete[] pIconBytes;
pIconBytes = new BYTE[nSize];
ret = ReadFile(hIconFile, (LPVOID)pIconBytes, nSize, &dwReserved, NULL);
if (!ret)
{
break;
}
cout << pGrpIconDir->idEntries[i].nID << endl;

//更新每一个ID对应的RT_ICON信息
ret = UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(pGrpIconDir->idEntries[i].nID), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), (LPVOID)pIconBytes, nSize);
if (!ret)
{
break;
}
}
//结束EXE资源的更新操作
if (pIconBytes != NULL)
{
delete[] pIconBytes;
}
EndUpdateResource(hUpdate, false);
}
//清理资源并关闭Icon文件,到此更新操作结束!
delete[] pGrpIconDir;
delete[] pIconDirEntry;
CloseHandle(hIconFile);

}



int main() {

cout << "正在替换图标" << endl;

CString dIconAddress ="C:\\Users\\akmoban\\Desktop\\测试\\图标测试\\icon\\25-32X32_0000.ico";
CString dExeAddress = "C:\\Users\\akmoban\\Desktop\\测试\\West263Domain.exe";

changedExeIcon(dExeAddress, dIconAddress);

system("pause");
return 0;
}




替换后原图标也不见了,0个图标为空,1图标才有内容


...全文
196 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
小米渣的逆袭 2021-08-04
  • 打赏
  • 举报
回复

楼主成功了吗

xcfdsarfew 2019-03-23
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
https://blog.csdn.net/aasmfox/article/details/24571111


方法替换成功了 谢谢!!!!!
xcfdsarfew 2019-03-23
  • 打赏
  • 举报
回复
引用 2 楼 xcfdsarfew 的回复:
引用 1 楼 schlafenhamster 的回复:
https://blog.csdn.net/aasmfox/article/details/24571111
你这个好像是VB的吧


底下有C++的,我先试试 3Q
xcfdsarfew 2019-03-23
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
https://blog.csdn.net/aasmfox/article/details/24571111
你这个好像是VB的吧

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧