我想使用Delphi更改以前生成的EXE文件的主图标。 EXE文件也是由我使用Delphi生成的。但我希望用户能够更改其图标。
我尝试使用UpdateResource函数更改RT_GROUP_ICON和RT_ICON均未成功:
procedure UpdateExeIcon(Const IconFilename, ExternalExeFilename:string);
var
Stream : TFileStream;
hDestRes : THANDLE;
lpData : Pointer;
cbData : DWORD;
begin
Stream := TFileStream.Create(IconFilename,fmOpenRead or fmShareDenyNone);
try
Stream.Seek(0, soFromBeginning);
cbData:=Stream.Size;
if cbData>0 then
begin
GetMem(lpData,cbData);
try
Stream.Read(lpData^, cbData);
hDestRes:= BeginUpdateResource(PChar(ExternalExeFilename), False);
if hDestRes <> 0 then
begin
//if UpdateResource(hDestRes, RT_ICON,PChar('1'),1033,lpData,cbData) then
if UpdateResource(hDestRes, RT_GROUP_ICON,PChar('MAINICON'),1033,lpData,cbData) then
begin
if not EndUpdateResource(hDestRes,FALSE) then RaiseLastOSError;
end else RaiseLastOSError;
end else RaiseLastOSError;
finally
FreeMem(lpData);
end;
end;
finally
Stream.Free;
end;
end;
答案 0 :(得分:6)
有多个错误:
UpdateResource(hDestRes, RT_ICON,PChar('1'),1033,lpData,cbData)
中,lpName
参数有两种工作方式:PChar('1')
将显示为文本,而MakeIntResource(1)
将显示为数字。您想要后一种,而不是前一种。RT_ICON
,您必须提供实际的图标有效载荷,而不是整个图标文件。现在,您要做的是后者,而不是前者。查看Icon文件的外观,然后查看资源仅包含的内容。RT_GROUP_ICON
是“仅”描述现有RT_ICON
资源的索引,应根据更新的图标进行修补(除非宽度,高度,颜色,像素深度和有效载荷长度都是相同)。在这里填写文件内容毫无意义。
上面您看到Resource Hacker显示我们要更新的资源的原始字节。 128
是十六进制的字节长度。
在上方看到HxD显示整个图标文件-我选择了第一个图标有效载荷所在的部分:从偏移量26
开始长度为128
(均为十六进制)。两个字节序列都匹配。
如果您执行了所有操作(使用MakeIntResource(1)
上的RT_ICON
并仅提供图标文件的图片数据),那么您就可以了-对我来说很好:我的EXE然后显示了新的Windows'资源管理器中的图标(尚未执行)。还应该完成RT_GROUP_ICON
的更新,因为我不确定它似乎在什么地方无效以及何时突然变成问题。在十六进制编辑器中查看文件,在资源编辑器中查看EXE将使您更好地理解所有操作。进一步阅读: