![]() |
Richtiges einblenden von Formularen
Liste der Anhänge anzeigen (Anzahl: 1)
Aus reiner Effekthascherei hatte ich vor ein Formular einzublenden. Der ganze Effekt sollte ca 1 Sekunde dauern.
Relaisiert habe ich das ganze so:
Delphi-Quellcode:
Die Delay Funktion kommt hier aus dem
procedure Delay(Milliseconds: Integer);
var Tick: DWord; Event: THandle; begin Event := CreateEvent(nil, False, False, nil); try Tick := GetTickCount + DWord(Milliseconds); while (Milliseconds > 0) and (MsgWaitForMultipleObjects(1, Event, False, Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do begin Application.ProcessMessages; Milliseconds := Tick - GetTickcount; end; finally CloseHandle(Event); end; end; procedure TForm2.FadeIn2; var zeitabschnitt: Integer; n: Integer; firstt: Cardinal; begin firstt:=gettickcount; zeitabschnitt:=1000 div 255 ; AlphaBlendValue:=0; show; if zeitabschnitt>0 then begin for n := 0 to 255 do begin delay(zeitabschnitt); AlphaBlendValue:=n; update; end; end; caption:=Format('Zeit für Fadein 2: %d ms',[gettickcount-firstt]); end; ![]() Daraufhin habe ich mich hier ein bischen umgesehen und folgende Funktion in der ![]()
Delphi-Quellcode:
Hier kamen folgende Zeiten Zustande:
procedure TForm2.FadeIn;
var n: Integer; firstt: Cardinal; Pause: Boolean; begin firstt:=gettickcount; AlphaBlendValue:=0; show; pause:=true; //langsam sichtbar machen for n := 1 to 8 do begin Pause := not Pause; if Pause then begin AlphaBlendValue := n*32-1; end; if n<8 then Refresh; sleep(5); end; caption:=Format('Zeit für Fadein: %d ms',[gettickcount-firstt]); end; Win 2000: 312 ms Vista : 47 ms XP : 200 ms Für mich stellen sich jetzt zwei Fragen. 1. Wieso ist das Laufzeitverhalten so unterschiedlich ? 2. Gibt es eine Möglichkeit diesen Einblendeffekt zeitlich zu steuern ? Ich habe das ganze auch mal als Delphi 6 Projekt hier angehängt. Der gleiche Effekt tritt aber auch bei Delphi 2010 auf. |
Re: Richtiges einblenden von Formularen
So kleine Zeiteinheiten kannst'e im Grunde vergessen.
Die Zeitauflösung seitens Windows liegt für Sleep/Delay/GetTickCount/Timer bei aktuell durchschnittlichen Intervallen von je 15-16 ms. Fazit: Bei diesen kurzen Intervallen für deine Pausen können diese nichtmal halbwegs richtig eingehalten werden. Hier kommt es also besser, wenn die Schleife für eine bestimmte Zeit läuft und nicht eine bestimmte Anzahl und der "Fortschritt" des Einblenden über die aktuelle Zeit errechnet wird. etwa so
Delphi-Quellcode:
C := GetTickCount;
while GetTickCount - C <= 765 do begin AlphaBlendValue := Min((GetTickCount - C) div 3 , 255); Application.ProcessMessages; end; AlphaBlendValue := 255; |
Re: Richtiges einblenden von Formularen
Ok, verstehe ich und funktioniert auch gut. Danke erst einmal.
Wenn ich dann die Zeiten richtig interpretiere, bedeutet es ja dass die minimale Zeit für das Delay entweder vom Betriebssystem oder der Prozessorgeschwindigkeit abhängig ist, oder beides. Hier noch mal die Zeiten für meine Version mit Delay: Win 2000: 8016 ms Vista : 764 ms XP : 2724 ms Der XP Rechner war dabei ein virtueller PC auf dem Vistarechner. Was ist denn der ausschlaggebende Faktor für die Genauigkeit von Delay ? |
Re: Richtiges einblenden von Formularen
Bei Delay hängen diese Gesamtzeiten vom OS und dem PC ab, also von der Auflösung des internen Timers.
Und dann hängen sie auch noch von der Auslastung der CPU und des Programmes. ein einfaches Beispiel: benötigt: ein Button, Memo und ein Edit (für das Delay)
Delphi-Quellcode:
Bedenke jetzt noch, daß bei dir relativ viel gemacht wird (so Einiges muß ja neu berechnet und gezeichnet werden), welches in deine Gesamtzeit mit einberechnet werden muß.
procedure TForm1.Button1Click(Sender: TObject);
var c, d, p, a: Cardinal; begin p := StrToInt(Edit1.Text); a := 2000 div p; // 2 sec Memo1.Lines.Clear; AlphaBlend := True; c := GetTickCount; while a > 0 do begin d := GetTickCount; Delay(p); {start - irgendwas machen} Memo1.Lines.Add(IntToStr(GetTickCount - d)); AlphaBlendValue := AlphaBlendValue + 1; Repaint; Application.ProcessMessages; {ende - irgendwas machen} Dec(a); end; Memo1.Lines.Add('= ' + IntToStr(GetTickCount - c)); AlphaBlend := False; end; Probier das Beispiel einfach mal mit 100, 10 und 1 Millisekunde aus. Seit Vista gibt es eine andere Desktopverwaltung, wobei der Desktopmanager alle Fenstern zwischenspeichert und demnach nur noch die "fertigen" Bilder verrechnen/überblenden muß, wärend die älteren OS dafür gleich mal den ganzen Desktop und fast alle Fenster neu zeichnen lassen müssen. |
Re: Richtiges einblenden von Formularen
Ist einleichtend. Danke noch einmal für Deine ausführlichen Erklärungen. Bei einem Timer habe ich auch immer die minimale Auflösung im Kopf. Hier hatte ich da aber absolut nicht dran gedacht
|
Re: Richtiges einblenden von Formularen
Kannst es auch mit AnimateWindow machen.
Mehr dazu findest Du in der Hilfe
Delphi-Quellcode:
procedure TForm1.FormShow(Sender: TObject);
begin AnimateWindow(self.Handle, 1000,AW_BLEND ) end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz