title: How can I smooth minimize a window before removing the taskbar button when minimize/restore animations are on?
body: <p>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. </p>
  
  <p>The simplest way to achieve this is to hide/show the form, a minimized window does not show anyway.</p>
  
  <pre><code>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;
  </code></pre>
  
  <p><br />The above application introduces a visual glitch when <em>"Animate windows when minimizing and maximizing"</em> 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.</p>
  
  <p><br />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 <code>WM_SYSCOMMAND</code>, which doesn't lead to any progress if I move the code (not to mention that a window can be minimized through a <code>ShowWindow</code> and others).</p>
  
  <p><br />Another solution might involve to know how long the animation takes place. <code>SystemParametersInfo</code> doesn't have it. Similar question <a href="https://stackoverflow.com/questions/23044933/detecting-windows-animation-settings">here</a> 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...). </p>
  
  <p><br />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.</p>