delphi 动态修改exe文件的图标

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, shellapi;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Edit1: TEdit;
    Label2: TLabel;
    Edit2: TEdit;
    OpenDialog1: TOpenDialog;
    OpenDialog2: TOpenDialog;
    StatusBar1: TStatusBar;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender:TObject);
begin
	Close;
end;

procedure TForm1.Button1Click(Sender:TObject);
const
	readlen = 10; //每次读取字节数,可改变
	icolen = 766; //32*32图标长度,根据研究前126为图标头,后640为图标数据
var
	i, j, itemp, nPos:int64; //   nPos为目的图标在目的文件的位置
	ci, cj:array[0..readlen - 1] of char;
	SourceFile, DestFile:string; //如果要把记事本图标换成瑞星杀毒软件图标
	bOK:boolean; //则SourceFile='C:\windows\notepad.exe',DestFile:='C:\Program Files\rising\rav\ravmon.exe'
	SourceIcon, DestIcon:TIcon;
	SIconStream, s, sDest:TMemoryStream;
begin
  bOK := false;
  if OpenDialog1.Execute then
      SourceFile := OpenDialog1.FileName
  else
      exit;
  if AnsiUpperCase(ExtractFileExt(SourceFile)) <> '.EXE' then
  begin
      ShowMessage(AnsiUpperCase(ExtractFileExt(SourceFile)));
      exit;
  end;
  Edit1.Text := SourceFile;
  if OpenDialog2.Execute then
      DestFile := OpenDialog2.FileName
  else
      exit;
  if AnsiUpperCase(ExtractFileExt(DestFile)) <> '.EXE' then exit;
  Edit2.Text := DestFile;
  SourceIcon := TIcon.Create;
  case ExtractIcon(handle, PChar(SourceFile), UINT(-1)) of
    0:
    begin ShowMessage('源程序没有图标');
      exit;
    end;
    1:;
  else
      ShowMessage('源程序有多个图标,本程序选择第一个图标');
  end;
  SourceIcon.Handle := ExtractIcon(handle, PChar(SourceFile), 0);
      //选择第一个图标
  DestIcon := TIcon.Create;
        //选择第N个图标为   ExtractIcon(handle,PChar(Sourcefile), N - 1)
  case ExtractIcon(handle, PChar(DestFile), UINT(-1)) of
    0:
    begin 
      ShowMessage('目的程序没有图标');
      exit;
    end;
    1:;
  else
    ShowMessage('目的程序有多个图标,本程序选择第一个图标替换');
  end;
  DestIcon.Handle := ExtractIcon(handle, PChar(DestFile), 0); //选择第一个图标
  SIconStream := TMemoryStream.Create;
  DestIcon.SaveToStream(sIconStream);
  if sIconStream.size <> icolen then
  ShowMessage('SIcon.size<>icolen');
  SDest := TMemoryStream.Create;
  sDest.LoadFromFile(DestFile);
  i := 0;
  //j := 0; //以下程序查找目的图标在目的程序中的位置
  while i < sDest.size do
  begin
    itemp := i;
    j := 126;
    cj := '';
    while (string(ci) = string(cj)) and (i < SDest.size) and (j < icolen) do
    begin
      i := i + readlen;
      j := j + readlen;
      SDest.Position := i;
      SDest.read(ci, readlen);
      SiconStream.Position := j;
      SiconStream.Read(cj, readlen);
    end;
    if j < icolen then
      i := itemp + 1 //没找到
    else
    begin
      nPos := itemp; //找到
      bOK := true;
      break;
    end;
  end;
  if bOK = false then exit; //目标文件二进制码中未找到图标
  SIconStream.Clear; //将源程序图标存入
  SourceIcon.SaveToStream(SIconStream);
  SIconStream.position := 126;
  s := TMemoryStream.Create;
  sDest.Position := 0;
  s.CopyFrom(sDest, nPos); //将目的程序图标前数据拷入
  s.CopyFrom(SIconStream, 640); //将源程序图标拷入
  if sDest.size > sDest.Position + 640 then //将目的程序剩余数据拷入
  begin
    sDest.Position := sDest.Position + 640;
    s.CopyFrom(sDest, sDest.Size - sDest.Position);
  end;
  s.SaveToFile(Extractfilepath(application.exename) + 'Result.exe');
  SourceIcon.Free;
  DestIcon.Free; //改造好的程序存放在本目录Result.exe文件中
  SIconStream.Free;
  s.Free;
  sDest.Free;
  ShowMessage(Extractfilepath(application.exename) + 'Result.exe');
end;
  //以上程序可以将目的程序的第一个图标换成源程序的第一个图标,经实证很多程序有二个
  //或更多图标,转换原理相似,不在陈述
end.




                
Delphi是一种可视化的编程语言和集成开发环境,可用于创建各种应用程序。修改文件图标是其中的一个功能,下面介绍如何使用Delphi来实现该功能。 我们可以使用ShellAPI单元中的ExtractIconEx函数来获取系统中的图标,并使用SHChangeNotify函数通知系统文件更改。 首先,在程序中添加ShellAPI单元,然后创建一个TImageList组件,其用于存储我们获取到的图标。接下来定义一个函数GetFileIcon用于获取文件图标。 函数的代码如下: procedure GetFileIcon(const AFileName: string; ImageList: TImageList; var IconIndex: integer); var Icon: HICON; IconCount: integer; begin IconCount := ExtractIconEx(PChar(AFileName), -1, nil, nil, 0); if IconCount > 0 then begin IconIndex := ImageList.AddIcon(Icon); DestroyIcon(Icon); end; end; 接着,在主窗体的OnCreate事件中定义一个图标索引值,用于保存我们刚刚添加的图标: var IconIndex: integer; ... procedure TForm1.FormCreate(Sender: TObject); begin ... IconIndex := -1; end; 最后,在我们需要修改文件图标的地方,我们可以调用GetFileIcon函数来获取需要修改文件图标,然后将其设置为相应的文件图标。 代码如下: procedure TForm1.Button1Click(Sender: TObject); var Icon: HICON; FileInfo: TSHFileInfo; begin if SelectDirectory('请选择需要修改图标的目录', '', s) then begin if IconIndex = -1 then begin Icon := LoadIcon(hInstance, 'MAINICON'); ImageList1.Clear; ImageList_AddIcon(ImageList1.Handle, Icon); IconIndex := ImageList1.Count - 1; end; SHGetFileInfo(PChar(s), 0, FileInfo, SizeOf(FileInfo), SHGFI_ICON or SHGFI_SMALLICON); FileInfo.hIcon := ImageList1.GetIcon(IconIndex); SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil); ShowMessage('文件图标修改成功!'); end; end; 通过以上步骤,我们就可以使用Delphi实现修改文件图标的功能了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值