Brak animacji podczas minimalizacji przy BorderStyle=bsNone

0

Delphi 10.4, testowałem tylko na Windows 8.1 ale przypuszczam, że to nie tego wina. Mam wrażenie, że kiedyś to robiłem za pomocą DrawAnimatedRects przy włączonym SPI_SETANIMATION ale teraz nie widać efektu. Nawet jak minimalizuję do traya przy bsSizeable to nie ma animacji. Okno jest tylko ukrywane. Przy bsSizeable system ładnie wszystko animuje ale programowo nie widać efektu. Jak pokazać tą animację? Za wszelkie rady z góry dzięki. Poniżej testowany kod DrawAnimatedRects:

uses
  SysUtils, Classes, Math, ShellApi, Messages, Graphics, Windows, Forms,
  Vcl.Controls, Vcl.StdCtrls, Vcl.Dialogs;

procedure ShowAnimation(Form: TForm);

implementation

function SetAnimation(Animation: Boolean; AI: TAnimationInfo): Boolean;
begin
  FillChar(ai, SizeOf(AI), 0);
  AI.cbSize := SizeOf(AI);
  if Animation then
    ai.iMinAnimate := 1
  else
    ai.iMinAnimate := 0;
  Result := SystemParametersInfo(SPI_SETANIMATION, 0, @AI, SPIF_SENDCHANGE);
end;

function GetWindowAnimation(var AI: TAnimationInfo): Boolean;
begin
  FillChar(AI, SizeOf(ai), 0);
  AI.cbSize := SizeOf(AI);
  if not SystemParametersInfo(SPI_GETANIMATION, AI.cbSize, @AI, SPIF_SENDCHANGE) then
    RaiseLastOSError;
  Result := not (AI.iMinAnimate = 0);
end;

procedure ShowAnimation(Form: TForm);
var
  RectFrom, RectTo: TRect;
  abd: TAppBarData;
  AI: TAnimationInfo;
begin
  if not (GetWindowAnimation(AI)) then
    SetAnimation(True, AI);

  FillChar(abd, SizeOf(abd), 0);
  abd.cbSize := SizeOf(abd);
  if SHAppBarMessage(ABM_GETTASKBARPOS, abd) = 0 then
    Exit;

  RectTo := abd.rc;

  RectFrom := Application.MainForm.ClientRect;
  if not (DrawAnimatedRects(Form.Handle, IDANI_CAPTION, RectFrom, RectTo)) then
    ShowMessage('Error: DrawAnimatedRects');
end;
1

Na ile pamiętam animacja się odbywa podczas zmiany ClientSize czyli nie powinna się odbywać podczas zmiany rodzaju ramki.
Zawsze możesz obliczyć rozmiar całego okna z ramkami, ustawić bsNone, zmienić ClientSize na wyliczony rozmiar, po czym ustawić animacje i zmniejszyć do poprzedniego rozmiaru ClientSize,

0
_13th_Dragon napisał(a):

Na ile pamiętam animacja się odbywa podczas zmiany ClientSize czyli nie powinna się odbywać podczas zmiany rodzaju ramki.
Zawsze możesz obliczyć rozmiar całego okna z ramkami, ustawić bsNone, zmienić ClientSize na wyliczony rozmiar, po czym ustawić animacje i zmniejszyć do poprzedniego rozmiaru ClientSize,

Dzięki za podpowiedź, mimo że za bardzo jej nie zrozumiałem.

Chwilowo sobie poradziłem ustawiając przed minimalizacją BorderStyle := bsSingle; a po przywróceniu BorderStyle := bsNone;

Dalej trochę boli mnie animacja do Traya, którą nie wiem jak zrobić, mimo że chwilowo jej nie potrzebuję. Jak zmusić kod z pierwszego postu do działania?

0

Dokładnie tak samo, jak opisałem wyżej. Musisz przenieść okienko do rozmiaru i pozycji tray'a na ekranie i puścić animacje. Po zakończeniu dopiero zrobić hide.

0
_13th_Dragon napisał(a):

Dokładnie tak samo, jak opisałem wyżej. Musisz przenieść okienko do rozmiaru i pozycji tray'a na ekranie i puścić animacje. Po zakończeniu dopiero zrobić hide.

Jeszcze raz dzięki za podpowiedź, naprowadziłeś mnie na rozwiązanie, mimo że nie udało mi się zmusić "DrawAnimatedRects" do działania. Chwilę testowałem i wyszło mi na to, że po włączeniu animacji "SPI_SETANIMATION" przesuwanie okna jest animowane. Do testów stworzyłem procedurę testową, która o dziwo działa bez DrawAnimatedRects, przykład poniżej. Funkcja SetAnimation znajduje się w pierwszym poście. Osobiście chwilowo, suma summarum, z tego nie skorzystałem tylko z oryginalnej - automatycznej animacji do TaskBara przy Minimize i Restore ale może komuś się przyda np. do animacji do Traya. Robiłem to już jakiś czas temu i nie jestem pewien czy nie jest to zależne od innych ustawień.

procedure ShowAnimation(Form: TForm);
var
  AI: TAnimationInfo;
begin
  if not (GetWindowAnimation(AI)) then
    SetAnimation(True, AI);

  Form.BorderStyle := bsSizeable;
  Form.ClientWidth  := 100;
  Form.ClientHeight := 100;
  Form.Top          := 10;
  Sleep(10);
  Form.Top          := 100;
  Sleep(10);
  Form.Top          := 200;
  Sleep(10);
  Form.Top          := 300;
  Sleep(10);
  Form.Top          := 400;
  Sleep(10);
  Form.Top          := 500;
  Sleep(10);
  Form.Top          := 600;
  Sleep(10);
  Form.Top          := 700;
  Sleep(10);
  Form.Top          := 800;
  Sleep(10);
  Form.Top          := 900;
  Sleep(10);
  Form.Top          := 1000;
  Form.BorderStyle := bsNone;
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1