在运行时用另一个.exe文件的图标替换VCL表单的图标?

时间:2015-03-01 19:29:05

标签: delphi icons delphi-xe7

使用Delphi XE7,我想在运行时更改当前VCL表单(不是应用程序)的图标。所以我尝试了这段代码:

procedure TForm1.LoadExeIcon(const AExeFileName: string);
var
  Icon: TIcon;
begin
  Icon := TIcon.Create;
  try
    Icon.Handle := ExtractIcon(HInstance, PWideChar(AExeFileName), 0);
    Self.Icon.Assign(Icon);
  finally
    Icon.Free;
  end;
end;

然后,应该在窗口的左上角(小图像格式)和任务栏(大图像格式)中显示更改的图标。

它可以工作,但是有一个小问题:窗口左上角的新小图标看起来很模糊,据说是因为exe文件中的大图像被拉伸到较小的尺寸。

这是小图像在原始exe程序窗口中的显示方式:

enter image description here

这就是替换后小图像在测试程序中的样子:

enter image description here

任务栏中的大图标看起来很完美。

那么如何让小图标看起来像原始的exe文件一样好看?

编辑:

我遵循了大卫的建议,这是工作的解决方案。为了让蛋糕真的很甜,我在任务栏图标上添加了一个叠加图标:

procedure TForm1.LoadExeIcon(const AExeFileName: string);
// Load Large and Small Icon from Exe file and assign them to the Form Icon
// Add Overlay to Taskbar Icon
var
  LIcon: HICON;
  SIcon: HICON;
  OLIcon: TIcon;
  NumberOfIconsInExeFile: Integer;
begin
  NumberOfIconsInExeFile := ExtractIconEx(PWideChar(AExeFileName), -1, LIcon, SIcon, 0);
  if NumberOfIconsInExeFile > 0 then // if there are any icons in the exe file
  begin
    ExtractIconEx(PWideChar(AExeFileName), 0, LIcon, SIcon, 1);
    SendMessage(Form1.Handle, WM_SETICON, 1, LIcon);
    SendMessage(Form1.Handle, WM_SETICON, 0, SIcon);
  end;

  // apply an overlay icon to the taskbar icon with new TTaskbar component:
  OLIcon := TIcon.Create;
  try
    ilTest.GetIcon(0, OLIcon);
    Taskbar1.OverlayIcon.Assign(OLIcon);
    Taskbar1.OverlayHint := 'My Hint'; // does not work?
    Taskbar1.ApplyOverlayChanges;
  finally
    OLIcon.Free;
  end;
end;

2 个答案:

答案 0 :(得分:1)

致电ExtractIconEx以提取大图标和小图标。

但是,请注意VCL有一个设计缺陷,在Delphi 1中引入,并且不允许您设置小图标和大图标。在我看来,您最好忽略Icon属性并手动发送WM_SETICON。每个图标大小一次。

答案 1 :(得分:-1)

尝试删除Icon.Free;,如果它有效,则意味着Icon.Free;也会使指定的图标处理无效