With Delphi XE7, I want to change the icon of the current VCL form (not of the application) at runtime. So I tried this code:
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;
The changed icon should then be visible on the left top corner of the window (small image format) and in the taskbar (large image format).
It works, but there is a small problem: The new small icon in the top left corner of the window looks blurred, supposedly because the large image from the exe file gets stretched to the smaller size.
This is how the small image looks in the window of the original exe program:
And this is how the small image looks in the test program after replacement:
The large icon in the taskbar looks perfect.
So how can I make the small icon look nice like in the original exe file?
EDIT:
I followed David's advice and here is the working solution. To make the cake really sweet I added an overlay icon to the taskbar icon:
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;