Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Formular im Thread neu erzeugen (https://www.delphipraxis.net/185984-formular-im-thread-neu-erzeugen.html)

khh 24. Jul 2015 10:11

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.

baumina 24. Jul 2015 10:16

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.

Der schöne Günther 24. Jul 2015 10:21

AW: Formular im Thread neu erzeugen
 
Was kann denn ein Thread in diesem Fall besser als ein simpler Timer?

Sir Rufo 24. Jul 2015 10:47

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:
procedure TFooForm.SetDate( const Value : TDate );
begin
  if FDate <> Value then
  begin
    FDate := Value;
    GetData(); // Daten holen und präsentieren
  end;
end;
Jetzt kann man auch ganz gemütlich einen Timer nehmen, der - egal in welchem Intervall - das aktuelle Tagesdatum dort reinhämmert.

khh 24. Jul 2015 11:02

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?

Sir Rufo 24. Jul 2015 11:10

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?

khh 24. Jul 2015 11:11

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 :-)

Sir Rufo 24. Jul 2015 11:25

AW: Formular im Thread neu erzeugen
 
Wenn du befürchtest, dass der Refresh zu lange dauert, dann schau dir mal
http://www.delphipraxis.net/185749-f...-callback.html
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:
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;
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.

Bernhard Geyer 24. Jul 2015 11:31

AW: Formular im Thread neu erzeugen
 
Zitat:

Zitat von khh (Beitrag 1309718)
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?

Ganz Schlecht. VCL-Formulare und Threads! Da mag der Teufel schon eher das Weihwasser.
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.

frankyboy1974 24. Jul 2015 11:33

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

Mavarik 24. Jul 2015 11:57

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

khh 24. Jul 2015 12:18

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 ?

stahli 24. Jul 2015 12:22

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).

khh 24. Jul 2015 12:28

AW: Formular im Thread neu erzeugen
 
Zitat:

Zitat von stahli (Beitrag 1309732)
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).

da steh ich jetzt auf der Leitung :-(

Du meinst ich ermittle im Timer die Differenz bis 00:01 und setze damit den Timerintervall jedesmal neu?

stahli 24. Jul 2015 12:37

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.

frankyboy1974 24. Jul 2015 12:38

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

Mavarik 24. Jul 2015 12:44

AW: Formular im Thread neu erzeugen
 
Zitat:

Zitat von stahli (Beitrag 1309737)
MS := T als Millisekunden (bin jetzt nicht sicher, wie man das umrechnen muss)
if (MS > MaxInt) then Und in der nächsten Timerbehandlung das gleiche wieder.
Dann feuert der Timer nicht unnötig oft.

Echt? Weil ein Timer ja auch nur ein Interval von 49 Tagen kann?

stahli 24. Jul 2015 12:50

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]

khh 24. Jul 2015 13:17

AW: Formular im Thread neu erzeugen
 
Zitat:

Zitat von stahli (Beitrag 1309742)
[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]

und es wäre besser verständlich was gemeint ist ;-)

Sir Rufo 24. Jul 2015 13:19

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:
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.
Simpel und robust

Rollo62 25. Jul 2015 07:17

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:
// 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);
Das ist zwar für Fmx gedacht, sollte aber auch mit VCL Laufen.

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

stahli 25. Jul 2015 08:54

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: http://www.delphipraxis.net/1138047-post24.html


Aber eigentlich ist das Problem ja offenbar schon gelöst.

p80286 25. Jul 2015 09:27

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

khh 25. Jul 2015 12:12

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

baumina 27. Jul 2015 06:22

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.

bcvs 27. Jul 2015 06:58

AW: Formular im Thread neu erzeugen
 
Zitat:

Zitat von khh (Beitrag 1309731)
alsoo,
im OnTimer frage ich einfach ab, ob es 00:01 Uhr ist.
wenn ja gebe ich die alten Panels frei und erzeuge sie neu.

Wieso erzeugst du die Panels neu? Reicht es da nicht, ein paar Properties zu ändern?

pertzschc 27. Jul 2015 08:54

AW: Formular im Thread neu erzeugen
 
Zitat:

Zitat von bcvs (Beitrag 1309892)
Zitat:

Zitat von khh (Beitrag 1309731)
alsoo,
im OnTimer frage ich einfach ab, ob es 00:01 Uhr ist.
wenn ja gebe ich die alten Panels frei und erzeuge sie neu.

Wieso erzeugst du die Panels neu? Reicht es da nicht, ein paar Properties zu ändern?

Er hat es leider noch nicht verstanden, dass er bei den Elementen auf dem Panel einfach nur neue Werte zuweisen muss...
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