在运行时用另一个 .exe 文件的图标替换 VCL 窗体的图标?
Replace the icon of a VCL form with the icon of another .exe file at runtime?
使用 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;
更改后的图标应该会出现在 window(小图像格式)和任务栏(大图像格式)的左上角。
它有效,但有一个小问题:window 左上角的新小图标看起来很模糊,据说是因为 exe 文件中的大图像被拉伸到较小的尺寸。
这是小图像在原始 exe 程序 window 中的样子:
这是替换后小图像在测试程序中的样子:
任务栏中的大图标看起来很完美。
那么如何让小图标看起来像原始exe文件中的那样好看呢?
编辑:
我听从了 David 的建议,这里是可行的解决方案。为了使蛋糕真的很甜,我在任务栏图标上添加了一个叠加图标:
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;
尝试删除 Icon.Free;
,如果有效,则意味着 Icon.Free;
也会使分配的图标句柄无效
调用ExtractIconEx
提取大图标和小图标。
但是,请注意 VCL 在 Delphi1 中有一个设计缺陷,它不允许您同时设置小图标和大图标。在我看来,您最好忽略 Icon
属性 并手动发送 WM_SETICON
。每个图标大小一次。
使用 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;
更改后的图标应该会出现在 window(小图像格式)和任务栏(大图像格式)的左上角。
它有效,但有一个小问题:window 左上角的新小图标看起来很模糊,据说是因为 exe 文件中的大图像被拉伸到较小的尺寸。
这是小图像在原始 exe 程序 window 中的样子:
这是替换后小图像在测试程序中的样子:
任务栏中的大图标看起来很完美。
那么如何让小图标看起来像原始exe文件中的那样好看呢?
编辑:
我听从了 David 的建议,这里是可行的解决方案。为了使蛋糕真的很甜,我在任务栏图标上添加了一个叠加图标:
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;
尝试删除 Icon.Free;
,如果有效,则意味着 Icon.Free;
也会使分配的图标句柄无效
调用ExtractIconEx
提取大图标和小图标。
但是,请注意 VCL 在 Delphi1 中有一个设计缺陷,它不允许您同时设置小图标和大图标。在我看来,您最好忽略 Icon
属性 并手动发送 WM_SETICON
。每个图标大小一次。