I am minimizing a form to system tray (display a tray icon) while keeping its taskbar button when it is not minimized. This implies removing the taskbar button when the form is minimized and restoring it otherwise.
The simplest way to achieve this is to hide/show the form, a minimized window does not show anyway.
type
TForm1 = class(TForm)
TrayIcon1: TTrayIcon;
procedure TrayIcon1DblClick(Sender: TObject);
protected
procedure WMSize(var Message: TWMSize); message WM_SIZE;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.WMSize(var Message: TWMSize);
begin
inherited;
case Message.SizeType of
SIZE_MINIMIZED:
if not TrayIcon1.Visible then begin
TrayIcon1.Visible := True;
Hide;
end;
SIZE_RESTORED, SIZE_MAXIMIZED:
if TrayIcon1.Visible then begin
Show;
Application.BringToFront;
TrayIcon1.Visible := False;
end;
end;
end;
procedure TForm1.TrayIcon1DblClick(Sender: TObject);
begin
Show;
WindowState := wsNormal;
end;
The above application introduces a visual glitch when "Animate windows when minimizing and maximizing" setting of the OS is on (accessible through 'SystemPropertiesPerformance.exe'). The minimize window animation is skipped. It appears that the animation actually takes place after the window is minimized. In the code, the window is already hidden by then.
One solution could be to have a notification when the window manager is done with the animation and hiding the form after that. I can't find any. When, for instance, you use the taskbar button minimizing the window, the last message sent is the WM_SYSCOMMAND
, which doesn't lead to any progress if I move the code (not to mention that a window can be minimized through a ShowWindow
and others).
Another solution might involve to know how long the animation takes place. SystemParametersInfo
doesn't have it. Similar question here tries to deal with the animation displayed when a window is first shown, although that animation seems to be related with DWM and minimize/maximize animation precedes DWM. No conclusive solution there either. Like in that question, a 250ms delay seems to work fine. But I'm not sure this is a universally sound delay. I'm not even sure a discrete delay would be definitive, perhaps a stutter would cause it to extent (not that it would matter much, but anyway...).
I also tried to actually remove the taskbar button, without hiding the form. But it's more clumsy and it doesn't change the output: the animation is skipped.
AnimateWindow()
? – andlabsIDANI_CAPTION
is3
) - maybe this helps. – AmigoJack