Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName) (https://www.delphipraxis.net/195976-fensteranimation-deaktivieren-bei-tstylemanager-trysetstyle-sstylename.html)

Codehunter 12. Apr 2018 08:11

Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
Moin,

mir ist aufgefallen, dass bei einem Wechsel des VCL-Style zur Laufzeit mit
Delphi-Quellcode:
TStyleManager.TrySetStyle(sStyleName)
anscheinend die Fenster neu erstellt werden. Dabei animiert Windows das "Aus- und wieder Ein-Fading". Das wirkt dann ziemlich unprofessionell und gibt außerdem Probleme mit Flickern bei Non-DoubleBuffered Fenstern. Manche etwas schludrig geschriebene Komponenten produzieren gar AVs.

Wenn ich allerdings Programmkompatibilität für das Programm auf "Basic" stelle, was bei Windows 7 zu der hässlichen Aero-Basic-Oberfläche führt, dann wuppt der Style-Wechsel ohne jegliche Animation in Sekundenbruchteilen und besagte Proleme mit Drittkomponenten (vermutlich ungültige Canvas-Handle) verschwinden auch.

Kann ich evtl. die Fensteranimation (auch beim Minimieren und Maximieren) über CreateParams beeinflussen/deaktivieren? Also nicht per Manifest die Anwendung in den Basic-Modus zwingen sondern nur die Fenster-Animationen abschalten.

Grüße
Cody

Uwe Raabe 12. Apr 2018 08:27

AW: Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
Ich glaube, bei Windows 7 funktioniert das noch:

Delphi-Quellcode:
uses
  DwmApi;
...
  DwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
  TStyleManager.TrySetStyle(sStyleName);
  DwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
...

Codehunter 12. Apr 2018 08:34

AW: Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
@Uwe: Genau das habe ich auch schon probiert. Das zwingt aber, wie oben geschrieben, das gesamte Windows einschl. Taskleiste in den Aero-Basic-Modus (Bei Windows 7). Genau das wollte ich ja nicht. Bei Windows 10 sehen die Animationen ein bisschen anders aus, die Fenster scheinen in sich zusammen zu fallen und werden anschließend wieder "aufgeblasen". Gibts denn keine Möglichkeit, selektiv nur die Fensteranimation zu deaktivieren, nicht das ganze Desktop-Theming?

EDIT/Nachtrag: Wie ich grade zufällig bemerkt habe, gibt es keine Animation, wenn ich Application.Mainform.BorderStyle:= bsNone einstelle. Allerdings sieht das dann ein bisschen seltsam aus, so "oben ohne" ;-)

Codehunter 12. Apr 2018 09:06

AW: Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
So, das hier scheint (zumindest unter Windows 10) zu funktionieren:
Delphi-Quellcode:
procedure TfrmMain.SetStyle(const AStyleName: string);
begin
  LockWindowUpdate(Handle);
  BorderStyle:= bsNone;
  TStyleManager.TrySetStyle(AStyleName, FALSE);
  Application.ProcessMessages;
  LockWindowUpdate(Handle);
  BorderStyle:= bsSizeable;
  LockWindowUpdate(0);
end;
Zugegeben, es ist ziemlich freaky. Das doppelte LockWindowUpdate scheint notwendig zu sein, weil sich beim TrySetStyle das WindowHandle ändert. Es flickert zwar noch ein bisschen, aber die Animation ist weg und der Style-Wechsel geht wesentlich schneller. Die Probleme mit den Drittkomponenten scheinen im Moment auch beseitigt.

Für Verbesserungen bin ich aber gerne zu haben :-)

KodeZwerg 12. Apr 2018 09:54

AW: Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
Ich verstehe noch nicht so ganz von was für einer Animation Du redest, eventuell kann Dir das dabei helfen
Delphi-Quellcode:
procedure TForm1.SetAnimation(Value: Boolean);
var
  Info: TAnimationInfo;
begin
  Info.cbSize := SizeOf(TAnimationInfo);
  BOOL(Info.iMinAnimate) := Value;
  SystemParametersInfo(SPI_SETANIMATION, SizeOf(Info), @Info, 0);
end;
Zu steuern über den Boolean. Das betrifft die Window Animation.

Codehunter 12. Apr 2018 10:51

AW: Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
Zitat:

Zitat von KodeZwerg (Beitrag 1398907)
Ich verstehe noch nicht so ganz von was für einer Animation Du redest, eventuell kann Dir das dabei helfen

Schau dir mal das Projekt FMC an, da habe ich das selbe Problem. Rechts oben über das Einstellungsmenü. Wenn der Style gewechselt wird, erfolgt eine doppelte Fade-Animation (bei Windows 10) bzw. eine doppelte Schrumpf- und Aufblas-Animation (bei Windows 7).

Dein Code bewirkt übrigens, leider, gar nichts:
Delphi-Quellcode:
procedure TfrmMain.SetStyle(const AStyleName: string);

  procedure SetAnimation(Value: Boolean);
  var
    Info: TAnimationInfo;
  begin
    Info.cbSize := SizeOf(TAnimationInfo);
    BOOL(Info.iMinAnimate) := Value;
    SystemParametersInfo(SPI_SETANIMATION, SizeOf(Info), @Info, 0);
  end;

begin
  SetAnimation(FALSE);
  TStyleManager.TrySetStyle(AStyleName, FALSE);
  SetAnimation(TRUE);
end;

KodeZwerg 12. Apr 2018 11:12

AW: Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
Der de-/aktiviert Animationseffekte beim minimieren maximieren, hat mit Theme an sich so nichts zu tun, mir fiel nur keine andere Window Animation ein. Ich lad mal FMC, falls Source beiliegt versuch ich mich ein bissl da reinzuwurschteln.

PS: Nutzt Du vielleicht manuell irgendwo diesen Befehl:
Delphi-Quellcode:
AnimateWindow(Form1.Handle, 3000, AW_BLEND);
o.ä. ?
Der bewirkt bei Windows das was Du beschreibst.

Codehunter 12. Apr 2018 11:22

AW: Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Source ist bei FMC nicht bei, kann ich auch nicht, weil z.T. rechtlich geschützt. Aber so weit weg bist du nicht mit der Fensteranimation beim Maximieren/Minimieren. Mach einfach ein beliebiges Fenster auf (Explorer, Word, whatever). Beim Öffnen wird es unter W10 sanft eingeblendet und beim Schließen sanft ausgeblendet. Das ist ja auch ganz nett und schön so. Nur stört genau das beim Stylewechsel, weil dabei per RecreateWnd das Fenster neu erstellt wird.

Ich hab dir mal eine ganz simple Demoanwendung beigepackt, die beim Buttonclick ein RecreateWnd auslöst. Dabei hast du dann genau den selben Fade-Out-In-Effekt (bei Windows 10), den ich deaktivieren möchte. Nicht global und schon gar nicht dauerhaft sondern nur fallbezogen während das Style gewechselt wird. Wenn du in dem Form dann Borderstyle von bsSizeable auf bsNone, bsToolWindow oder bsSizeToolWin stellst und dann auf den Button klickst, siehst du außer einem kurzen Verschwinden keine Animation. Es scheint also etwas mit den Border-Parametern zu tun zu haben.

KodeZwerg 12. Apr 2018 12:07

AW: Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
Ich habe Dein Demoprojekt wie folgt geändert mit dem Resultat das das Window nicht neu erstellt wird aber Inhalt aktualisiert wird.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure MyMessage(var Msg: TMessage); message CM_RECREATEWND;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.MyMessage(var Msg: TMessage);
begin
  if Msg.Result=0 then
  begin
    Label1.Caption:='W - '+IntToStr(Msg.WParam); // irgendwas anzeigen um eine sichtbare veränderung zu demonstrieren
    Label2.Caption:='L - '+IntToStr(Msg.LParam); // irgendwas anzeigen um eine sichtbare veränderung zu demonstrieren
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Self.RecreateWnd;
end;

end.
Hilft das?

Codehunter 12. Apr 2018 12:25

AW: Fensteranimation deaktivieren bei TStyleManager.TrySetStyle(sStyleName)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Lach, lustiger Effekt ^^ Jetzt hast du aber einen Fehler gemacht. Du musst in dem MessageHandler noch ein Result inherited setzen. Andernfalls wird das neu erstellte Fensterobjekt nicht richtig initialisiert. Bei mir hat das den Effekt, dass das Fenster zwar noch einen Moment auf dem Bildschirm zu sehen ist, aber technisch nicht mehr vorhanden. Bei einem Klick auf den Button geht der Klick wie durch ein Geisterfenster an das Fenster das dahinter liegt.

Angepasste Demo mit Stylewechsel im Anhang.

Nachtrag: Mit dem inherited ist das Problem wieder da.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:53 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz