![]() |
Formular im Thread neu erzeugen
Hallo zusammen,
ich habe eine Form auf der diverse Felder tagesabhängig dargestellt werden. Beim Programmstart werden die Felder in Abhängigkeit des entsprechenden Tages erzeugt. Jetzt kommt der Kunde auf die Idee, das Programm nicht mehr täglich neu zu starten, sondern durchlaufen zu lassen. Also werden die Felder auch dauernd so, wie beim Programmstart der Ausgangspunkt war, dargestellt. Ich habe nun die Idee in einem Thread die Uhrzeit abzufragen und bei 00:01 Uhr die Form neu zu erzeugen und wieder anzuzeigen. Was meint ihr zu dieser Lösung? Danke für eure Meinungen. |
AW: Formular im Thread neu erzeugen
Ich würde die Form nicht neu erzeugen, sondern nur die Procedure aufrufen, in der die Captions/Texte/Visibles entsprechend geändert werden.
|
AW: Formular im Thread neu erzeugen
Was kann denn ein Thread in diesem Fall besser als ein simpler Timer?
|
AW: Formular im Thread neu erzeugen
Eine ganz billige Lösung ist das verwenden einer Eigenschaft, die das Datum beinhaltet zu dem diese Form die Daten anzeigt.
Eine Änderung des Datums führt zum Laden der neuen Werte für eben dieses Datum.
Delphi-Quellcode:
Jetzt kann man auch ganz gemütlich einen Timer nehmen, der - egal in welchem Intervall - das aktuelle Tagesdatum dort reinhämmert.
procedure TFooForm.SetDate( const Value : TDate );
begin if FDate <> Value then begin FDate := Value; GetData(); // Daten holen und präsentieren end; end; |
AW: Formular im Thread neu erzeugen
Es geht darum, dass nicht nur das neue Datum angezeigt werden muss.
Abhängig vom Datum werden beim Erstellen der Form verschiedene Labels und deren Beschriftung geändert. Und was meint Ihr dazu, eben diesen angesprochenen Timer zu verwenden, um die Form neu zu erzeugen? Ich denke, ich komme um die Neuerstellung der Form nicht drum rum ? EDIT: oder eben im Timer die Procedure neu aufrufen wie Baumina meinte? |
AW: Formular im Thread neu erzeugen
Du hast eine Form (also eine Anzeige) und diese Anzeige soll etwas anderes anzeigen und dafür willst du die Form neu erstellen lassen?
Wenn du das Programm am Fernseher wechselt, schmeisst du dann auch den alten Fernseher weg und kaufst dir einen neuen? |
AW: Formular im Thread neu erzeugen
>> Wenn du das Programm am Fernseher wechselt, schmeisst du dann auch den alten Fernseher weg und kaufst dir einen neuen?
Guter Vergleich :-) |
AW: Formular im Thread neu erzeugen
Wenn du befürchtest, dass der Refresh zu lange dauert, dann schau dir mal
![]() an. Da habe ich genau so ein Szenario aufgezeigt. Gib der Form einfach einen Service an die Hand, wo diese einfach nachfragen kann.
Delphi-Quellcode:
Ob diese Daten vom Service jetzt im Thread oder nicht geholt werden, entscheidet der Service bzw. die Implementierung des Services. Der Form ist es so egal wie das dort bewerkstelligt wird.
procedure TFooForm.GetData();
begin RetrieveData := True; // Kreisenden Kringel anzeigen ;o) FSomeService.GetFooDataByDate( FDate, FooDataCallback ); end; procedure TFooForm.FooDataCallback( AResult: TFooData; AException: Exception; var ADispose : Boolean ); begin RetrieveData := False; if Assigned( AException ) then begin // Exception-Meldung in der Form anzeigen ErrorMessageLabel.Caption := AException.Message; end else begin ErrorMessageLabel.Caption := ''; PresentFooData( AResult ); // Daten im Formular anzeigen lassen end; end; |
AW: Formular im Thread neu erzeugen
Zitat:
Alles was mit der GUI zu tun hat muss im Hauptthread erfolgen! Ansonsten krachts an unmöglichen Stellen zu irgendeiner Zeit. Das Grundproblem ist hier das Win32-Controls nur im erzeugenden Thread gültig sind. |
AW: Formular im Thread neu erzeugen
Hallo,
wenn du nach dem MVC programmieren würdest, sollte dies eigentlich kein Problem darstellen. In meinem MVC-Framwork fragt jede GUI-Komponente das Model ob Sie gerade sichtbar ist, hier könntest du auch leicht dies vom aktuellen Datum abhängig machen, ob eine Komponente sichtbar ist oder nicht. mfg frank |
AW: Formular im Thread neu erzeugen
Du hast Doch sicherlich im FormCreate die Abfrage nach dem Wochentag...
Dann brauchst Du doch nur daraus eine procedure machen und die Aufrufen... Mavarik |
AW: Formular im Thread neu erzeugen
alsoo,
ich habe jetzt einen Timer den ich alle 45 Sekunden aufrufe. im OnTimer frage ich einfach ab, ob es 00:01 Uhr ist. wenn ja gebe ich die alten Panels frei und erzeuge sie neu. Klappt in einem ersten Test wunderbar. ;-) Ich überlege nur, ob die Abfrage alle 45 Sekunden, also einmal pro Minute nötig ist. ich denke schon, denn bei einem längeren Intervall "verpasst" der Timer die passende Uhrzeit, oder ? |
AW: Formular im Thread neu erzeugen
Du kannst auch die Differenzzeit bis 00:01 ermitteln und das Ergebnis in das Timerintervall schreiben (bzw. Maxint wenn die Millisekunden sonst zu viele wären).
|
AW: Formular im Thread neu erzeugen
Zitat:
Du meinst ich ermittle im Timer die Differenz bis 00:01 und setze damit den Timerintervall jedesmal neu? |
AW: Formular im Thread neu erzeugen
So etwa wie Wecker stellen:
T: TTime; MS: Real; I: Integer; ... T := (Morgen, 00:00:01) - Now; MS := T als Millisekunden (bin jetzt nicht sicher, wie man das umrechnen muss) if (MS > MaxInt) then I := MaxInt else I := Round(MS); Timer.Interval := I; Und in der nächsten Timerbehandlung das gleiche wieder. Dann feuert der Timer nicht unnötig oft. |
AW: Formular im Thread neu erzeugen
hallo,
du ermittelst wieviel Zeit noch bis 00:01 benötigt wird und setzt deinen Timer entsprechend neu. Wenn du also um 22:10 nachschaust, brauchst du nicht alle 45 Sekunden neu prüfen, ob bereits Mitternacht ist. Ich würde an dieser Stelle aber die allgemeine Relativitäts Theorie anführen. Wenn es bir jetzt 22:10 ist, und bei dir eine Sekunden vergangen ist, heisst dies nicht, dass bei mir auch nur eine Sekunde verganganen ist.:roll: mfg frank |
AW: Formular im Thread neu erzeugen
Zitat:
|
AW: Formular im Thread neu erzeugen
[OT]
kleiner Vorschlag: Ändere Deine Antwort in "ein Timer kann ein Intervall von 49 Tagen, dann braucht es in dem Fall keine MaxInt-Prüfung" (das klänge etwas netter) [/OT] |
AW: Formular im Thread neu erzeugen
Zitat:
|
AW: Formular im Thread neu erzeugen
Warum macht ihr euch das Leben so schwer? Ihr tut gerade so, als ob so ein Timer-Event die Monster-Performance-Bremse ist.
Delphi-Quellcode:
Simpel und robust
unit Form.MainForm;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls; type TForm1 = class( TForm ) EnsureCurrentDateTimer: TTimer; CurrentDateLabel: TLabel; procedure FormShow( Sender: TObject ); procedure EnsureCurrentDateTimerTimer( Sender: TObject ); procedure FormHide( Sender: TObject ); private FCurrentDate: TDate; procedure SetCurrentDate( const Value: TDate ); procedure DoRefreshFormData( ); procedure DoEnsureCurrentDate( ); protected property CurrentDate: TDate read FCurrentDate write SetCurrentDate; public end; var Form1: TForm1; implementation {$R *.dfm} uses System.DateUtils; procedure TForm1.DoEnsureCurrentDate; begin CurrentDate := Date; end; procedure TForm1.DoRefreshFormData; begin CurrentDateLabel.Caption := DateToStr( CurrentDate ); end; procedure TForm1.EnsureCurrentDateTimerTimer( Sender: TObject ); begin DoEnsureCurrentDate( ); end; procedure TForm1.FormHide( Sender: TObject ); begin EnsureCurrentDateTimer.Enabled := False; end; procedure TForm1.FormShow( Sender: TObject ); begin DoEnsureCurrentDate( ); EnsureCurrentDateTimer.Enabled := True; end; procedure TForm1.SetCurrentDate( const Value: TDate ); var LValue: TDate; begin LValue := DateOf( Value ); if FCurrentDate <> LValue then begin FCurrentDate := LValue; DoRefreshFormData( ); end; end; end. |
AW: Formular im Thread neu erzeugen
Hallo zusammen,
die Antworten finde ich alle richtig und schlüssig. Ich verstehe auch nicht ganz warum die Form neu geladen werden soll. Aber wenn es denn sein muss könnte man die Form in ein Panel bauen und per Runtime nachladen oder auswechseln: Ungefähr so:
Code:
Das ist zwar für Fmx gedacht, sollte aber auch mit VCL Laufen.
// AForm is newly created externally and then can be embedded to a control, such as a panel or a tabsheet.
procedure Form_EmbedTo(const AForm:TCustomForm; const AParent:TControl); begin while AForm.ChildrenCount>0 do AForm.Children[0].Parent:=AParent; end; // Und der Aufruf in Etwa mxNewForm := TMyNewForm.Create(nil); Form_EmbedTo(myNewForm, MyTargetPanel); Damit könnte - die neue Form im Thread erzeugt werden (warum auch immer) - die neue Form erzeugt werden - auf das Panel geworfen werden (das solte recht schnell gehen) - und danach die alte Form wieder entsorgt werden So sollte der Wechsel recht schnell gehen. Rollo |
AW: Formular im Thread neu erzeugen
Die Idee hat Karl-Heinz ja schon wieder verworfen.
Ein Formular aus einen Thread heraus zu erzeugen wird wegen späterer Zugriffskonflikte m.E. immer schief gehen. Wenn man das will, kann man Formulare auch direkt einbetten - z.B. so: ![]() Aber eigentlich ist das Problem ja offenbar schon gelöst. |
AW: Formular im Thread neu erzeugen
Mal so als Anmerkung,
meine Begeisterung für eine (tiefgreifende) Oberflächenänderung würde sich doch in engen Grenzen halten, wenn sie während eines Arbeitsvorgangs stattfindet. Gruß K-H |
AW: Formular im Thread neu erzeugen
ja, ich danke euch,
die Idee die Panels mittels Timer freizugeben und neu zu erstellen, funktioniert m.E. tadellos. Gruss KH |
AW: Formular im Thread neu erzeugen
Also doch nen Teil des Fernsehers wegwerfen ... aber wenn du zufrieden bist, müssen wir es wohl auch sein.
|
AW: Formular im Thread neu erzeugen
Zitat:
|
AW: Formular im Thread neu erzeugen
Zitat:
Grüße, Christoph |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:17 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