Autor Beitrag
makena76
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: Sa 19.06.04 17:41 
Hallo Leute,

ich würde gerne einige Unterfenster meiner Anwendung zu einer bestimmten Zeit schließen. Bisher habe ich das mit TTimer gemacht, musste aber leider feststellen, dass das nicht 100%ig funktioniert. Hatte da beim OnCreate die verbleibende Zeit errechnet und dies dem TTimer als Interval übergeben. Da gab es leider immer paar Sekunden Abweichung.

Nun würde ich es gerne mit einem Thread lösen. Habe das jetzt so probiert:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
 TAutoCloseForm = class(TThread)
  private
    procedure UpdateCounter; virtual;
  protected
    procedure Execute; override;
  public
    AutoCloseTime: TDateTime;
    constructor Create(CloseTime: TDateTime);
  end;
.
.
.
constructor TAutoCloseForm.Create;
begin
  Inherited Create(true);
  Priority:= tpIdle;
  Resume;
  AutoCloseTime:=CloseTime;
end;

procedure TAutoCloseForm.Execute;
begin
  while not terminated do
    Synchronize(UpdateCounter);
end;

procedure TAutoCloseForm.UpdateCounter;
begin
 if Now=AutoCloseTime then begin
  Terminate;
  //Close;
 end;
end;


Leider kann ich dann mit Close das Formular nicht schließen. Wie geht das?? Mit TfmForm2.Close geht es auch nicht :roll:

Auch und außerdem habe ich das Problem, wie ich die Uhrzeit dem Thread übergebe, diese soll in AutoCloseTime stehen...

Über Tipps würde ich mich freuen. Danke :-)

Ciao makena
Alstar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 827



BeitragVerfasst: Sa 19.06.04 19:00 
Hi makena.

Habe mir deinen Quelltext jetzt nicht gründlich durchgeschaut :) aber ich denke, du musst die Prozeduren (Terminate; Close etc) mit dem Formnamen "ansprechen". Zum Beispiel

ausblenden Quelltext
1:
2:
3:
4:
Form1.Close;
Form1.Terminate;
MainForm.Close;
etc ...


Alstar
makena76 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: So 20.06.04 09:34 
Hallo Alstar,

habe es damit auch schon probiert gehabt, da passiert einfach gar nichts.
EUOCheffe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 124



BeitragVerfasst: So 20.06.04 16:01 
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
  TAutoCloseForm = class(TThread)
  protected
    procedure Execute; override;
  public
    CloseForm    : TForm;
    AutoCloseTime: TDateTime;
    constructor Create(Form : TForm; CloseTime: TDateTime);
  end;

var
  Form1 : TForm1;
  Thrd  : TAutoCloseForm;

implementation
{$R *.dfm}

constructor TAutoCloseForm.Create(Form : TForm; CloseTime: TDateTime);
begin
  Inherited Create(true);
  AutoCloseTime:=CloseTime;
  CloseForm:=Form;
  Resume;
end;

procedure TAutoCloseForm.Execute;
begin
  while Now<AutoCloseTime do Sleep(0);
  PostMessage(CloseForm.Handle,WM_CLOSE,0,0);
  FreeOnTerminate:=True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Thrd:=TAutoCloseForm.Create(Form1,Now+1/24/60/6); //Now+10sec
end;


Das zu schliessende Form würd ich auch noch als Parameter übergeben (dann gehts auch für andere Forms). Beim Vergleich mit Now kein Gleichheitszeichen verwenden!!! Anstatt das noch zu synchronisieren, kann man auch einfach eine WM_CLOSE Nachricht senden. Resume erst ausführen, nachdem alle Variablen gesetzt sind. Falls es um +/- 20ms nicht ankommt, dann würd ich nicht die Priorität senken, sondern Sleep(0) verwenden (verbrennt keine CPU Zeit). Eventuell mit FreeOnTerminate Thread auch gleich wieder freigeben.
makena76 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: So 20.06.04 17:28 
Hi EUOCheffe,

ja super für den Code, damit klappt es perfekt. Allerdings ist damit die CPU-Auslastung bei 60% etwa. Wenn ich dann das Priority:= tpIdle; einsetze, dann ist sie bei Null. Was soll ich nun machen, bist Du Dir da sicher, dass tpIdle nicht optimal ist?

Ciao makena
makena76 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: So 20.06.04 17:57 
Kleiner Nachtrag:
Mit Now+1/24/60/6 wird es in 10 Sekunden geschlossen. Wenn ich stattdessen StrToTime('23:00:00') verwende, dann wird das Form sofort wieder geschlossem. Auch mit EncodeDate/DecodeDate habe ich rumprobiert. Das gibts doch nicht :roll:
EUOCheffe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 124



BeitragVerfasst: So 20.06.04 21:15 
Probier mal Sleep(1) statt Sleep(0). Tatsächlich ist bei tpIdle die verbrauchte CPU Zeit des Programms nur dann null, wenn ein anderes Programm mit höherer Priorität die ganze Zeit für sich in Anspruch nimmt.

Unit DateUtils einbinden und dann Today+StrToTime('23:00:00'). Guck dir mal die Delphi Hilfe zum Typ TDateTime an, damit du siehst, wie der codiert ist. Im Index findest du ausserdem den Eintrag "datetime routines", wo alle Datumsfunktionen aufgelistet sind. Damit kannst du so ziemlich alles machen.
makena76 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: So 20.06.04 23:37 
Super, danke Dir. Klappt alles bestens mit Sleep(1) :)