【问题标题】:Change icon of application on runtime在运行时更改应用程序的图标
【发布时间】:2016-02-03 22:48:13
【问题描述】:

我有一个带有特定图标的 EXE (App1.exe) 文件,以及带有另一个特定图标的另一个 EXE (App2.exe) 文件。

App2 作为资源嵌入在 App1 项目中,但我想停止使用该资源,并将整个工作留在 App1.exe 中。 但是,执行App1.exe后,我想将它保存在另一个文件中(将其复制到另一个文件),带有App2.exe的图标...我有App2.exe的.ico文件,这不是问题。但是当我将它复制到另一个文件时,如何让App1.exe带有原始图标,以及另一个带有App2.exe图标的App1.exe,这可以用简单的代码吗?

【问题讨论】:

  • 使用UpdateResource()替换复制文件的图标资源。
  • 复制 exe 文件是一个坏主意,原因有很多。使用命令行参数指定行为并根据这些参数选择图标。
  • 或者,而不是命令行参数,让您的 app1.exe 包含两个图标。使用互斥锁之类的机制让 app1 检查另一个实例是否已经在运行,然后切换到第二个图标。
  • @DavidHeffernan 问题是我的文件将替换原来的 Adob​​e PDF Reader,所以,我需要 exe 来获得 Adob​​e 的图标,以免搞砸......运行时,我需要文件本身才能拥有该图标。虽然第一个exe,没有意义留在这个图标。
  • 您使用 Adob​​e PDF Reader 图标的文件不仅侵犯了 Adob​​e 的版权,而且对于您的软件用户而言,它类似于恶意软件(如果不是,则伪装成合法软件)。这里的人不应该帮助您创建恶意软件。

标签: delphi


【解决方案1】:

我不确定我是否完全理解你想要什么 我认为您应该复制它然后更改图标
此代码将从另一个 exe 文件更新 exe 图标

unit iconchanger;


interface

uses windows;

  type
    PICONDIRENTRYCOMMON = ^ICONDIRENTRYCOMMON;
    ICONDIRENTRYCOMMON = packed record
    bWidth             : Byte;  // Width, in pixels, of the image
    bHeight            : Byte;  // Height, in pixels, of the image
    bColorCount        : Byte;  // Number of colors in image (0 if >=8bpp)
    bReserved          : Byte;  // Reserved ( must be 0)
    wPlanes            : Word;  // Color Planes
    wBitCount          : Word;  // Bits per pixel
    dwBytesInRes       : DWord; // How many bytes in this resource?
    end;

    PICONDIRENTRY      = ^ICONDIRENTRY;
    ICONDIRENTRY       = packed record
    common             : ICONDIRENTRYCOMMON;
    dwImageOffset      : DWord; // Where in the file is this image?
    end;

    PICONDIR           = ^ICONDIR;
    ICONDIR            = packed record
    idReserved         : Word; // Reserved (must be 0)
    idType             : Word; // Resource Type (1 for icons)
    idCount            : Word; // How many images?
    idEntries          : ICONDIRENTRY; // An entry for each image (idCount of 'em)
    end;

    PGRPICONDIRENTRY   = ^GRPICONDIRENTRY;
    GRPICONDIRENTRY    = packed record
    common             : ICONDIRENTRYCOMMON;
    nID                : Word;  // the ID
    end;

    PGRPICONDIR        = ^GRPICONDIR;
    GRPICONDIR         = packed record
    idReserved         : Word; // Reserved (must be 0)
    idType             : Word; // Resource type (1 for icons)
    idCount            : Word; // How many images?
    idEntries          : GRPICONDIRENTRY;  // The entries for each image
    end;

function UpdateApplicationIcon(srcicon : PChar; destexe : PChar) : Boolean;

implementation

function UpdateApplicationIcon(srcicon : PChar; destexe : PChar) : Boolean;
var hFile  : Integer;
    id     : ICONDIR;
    pid    : PICONDIR;
    pgid   : PGRPICONDIR;
    uRead  : DWord;
    nSize  : DWord;
    pvFile : PByte;
    hInst  : LongInt;
begin
result := False;
hFile := CreateFile(srcicon, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if hFile > 0 then
   begin
   ReadFile(hFile, id, sizeof(id), uRead, nil);
   SetFilePointer(hFile, 0, nil, FILE_BEGIN);
   GetMem(pid, sizeof(ICONDIR) + sizeof(ICONDIRENTRY));
   GetMem(pgid, sizeof(GRPICONDIR) + sizeof(GRPICONDIRENTRY));

   ReadFile(hFile, pid^, sizeof(ICONDIR) + sizeof(ICONDIRENTRY), uRead, nil);
   move(pid^, pgid^, sizeof(GRPICONDIR));

   pgid^.idEntries.common := pid^.idEntries.common;
   pgid^.idEntries.nID := 1;
   nSize := pid^.idEntries.common.dwBytesInRes;

   GetMem(pvFile, nSize);
   SetFilePointer(hFile, pid^.idEntries.dwImageOffset, nil, FILE_BEGIN);
   ReadFile(hFile, pvFile^, nSize, uRead, nil);
   CloseHandle(hFile);

   hInst:=BeginUpdateResource(destexe, False);
   if hInst > 0 then
      begin
      UpdateResource(hInst, RT_ICON, MAKEINTRESOURCE(1), LANG_NEUTRAL, pvFile, nSize);
      EndUpdateResource(hInst, False);
      result := True;
      end;

   FreeMem(pvFile);
   FreeMem(pgid);
   FreeMem(pid);
   end;
end;

end.

用名称iconchanger保存上面的单元并将其添加到您的项目复制文件后像这样调用它

procedure TForm1.BtnChangeIconClick(Sender: TObject);
begin
    iconchanger.UpdateApplicationIcon(PChar(SourceFileName), PChar(DestinationFileName));
end;

DestinationFileName 现在将拥有SourceFileName 图标

【讨论】:

  • 在 Delphi 10.3 + Windows 8 上不起作用。甚至试图清除图标缓存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-07
  • 2014-01-22
  • 2012-02-22
  • 2014-08-12
  • 2010-11-02
相关资源
最近更新 更多