Autor Beitrag
BigBasti
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 45

Win XP
D7
BeitragVerfasst: Di 31.01.06 22:06 
ich habe in mein programm einen timer gepackt, der die Sekunden und Minuten anzeigen soll, doch kommt es zeitweise vor, dass er Sekunden überspringt und zum beispiel von 12:12 (Minuten : Sekunden) auf 12:15 springt. Der Intervall des ontimer ereignisses ist 1000 (also genau eine sekunde), hier mal der code:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure Tform1.Timer1Timer(Sender: TObject);
begin
    if sek<59 then
     sek:=sek+1
     else begin sek:=0;
                if min<59 then
                min:=min+1
                else min:=0;
          end;

    uhrlabel.caption:='Zeit: ' + inttostr (st) + ':' + inttostr (min) + ' Uhr';
end;


kann mir jemand helfen, dieses problem zu lösen? wäre supernett :-D
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Di 31.01.06 22:17 
Wieso nimmst Du dafür nicht die Systemzeit? Dort kannst Du auch bei 0 anfangen, wenn Du zu einem bestimmten Zeitpunkt die Systemzeit abgreifst (z.B. in OnShow):
ausblenden 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:
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    time: TDateTime;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Caption := TimeToStr(Now-time);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  time := Now;
end;

end.


Der Timer an sich ist halt ein wenig ungenau, da man nicht voraussagen kann, wann die Anwendung wieder Prozess-Zeit zugewiesen bekommt. Aber mit Hilfe der Systemzeit kannst Du vermeiden, dass diese Sprünge Einfluss auf Deine Zähler haben.
digi_c
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1905

W98, XP
D7 PE, Lazarus, WinAVR
BeitragVerfasst: Mi 01.02.06 09:25 
Oder du benutzt einen HighPerformance Timer wie er z.B. bei Spielen eingesetzt wird. Aber ich weiß nicht ob das deinem Problem angemessen ist.
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: Mi 01.02.06 09:36 
user profile icondigi_c hat folgendes geschrieben:
Oder du benutzt einen HighPerformance Timer wie er z.B. bei Spielen eingesetzt wird. Aber ich weiß nicht ob das deinem Problem angemessen ist.


Dieser ist zum Timing gut, aber nicht zum Triggern. Er hat kein Ereignis und muss daher gepollt werden - bringt daher mehr Nachteile als Vorteile.

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
BigBasti Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 45

Win XP
D7
BeitragVerfasst: Mi 01.02.06 12:32 
vielen dank, ich werde es mal mit der systemzeit versuchen! wenns geklappt hat, sag ich bescheid :-D

edit: joar klappt so weit, nun hab ich aber ein paar fragen zum typ tdatetime!

ich möchte in meinem programm einen "schnelleren tagesablauf" (blöde formulierung) simulieren, deshalb benötige ich nur das anzeigen von Minuten (wobei eine minute einer sekunde in echtzeit ensprechen soll) und der stunden (wobei eine stunde einer minute in echtzeit entsprechen soll, also 60 sekunden in echtzeit). demzufolge soll die ausgabe in etwa wie 23:45 sein (Stunde:Minute), also müsste ich auch noch dafür sorgen, dass die echtzeitminuten im tdatetime nur bis 24 gehen (da sie im programm ja die stunden repräsentieren) und die echtzeitstunden nicht ausgegeben werden.

ist so etwas mit tdatetime verwirklichbar oder gibt es eine andere möglichkeit dies zu erreichen??
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 01.02.06 13:13 
Kleiner Nachtrag:
Ein TTimer ist nicht wirklich eine Uhr, die knallhart immer ein Ereignis auslöst (schön wärs). Windows verwaltet diese Timer und verschickt entsprechende WM_TIMER Nachrichten. Das ist natürlich blöd, wenn die Anwendung gerade in einer dicken Schleife ist, und die Nachrichten gar nicht abgearbeitet werden.

Abhilfe: Immer mal wieder 'Application.ProcessMessages' aufrufen. Dann klappt das auch mit dem Timer besser. Da es keine hochpräzise Quarzuhr ist, sondern nur eine Softwarelösung, kann man damit keinen Zähler hochzählen und dann erwarten, daß das Ergebnis genau ist. Die eingebaute Uhr (Time) ist dafür jedoch genau genug (+/- 20ms).

_________________
Na denn, dann. Bis dann, denn.
digi_c
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1905

W98, XP
D7 PE, Lazarus, WinAVR
BeitragVerfasst: Mi 01.02.06 13:39 
Ich habe festgestellt, das es aber auch Probleme gibt, wenn du z.B. mit dem Mauscursor auf die Fensterleisten Symbole(Minimieren,Schließen,..) gehst und dann ein Hint erscheint.
BigBasti Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 45

Win XP
D7
BeitragVerfasst: Mo 06.02.06 23:06 
ok ich habe nun folgendes festgestellt:

wenn ich eine variable mit dem timer mitlaufen lasse (siehe ganz oben) wird dieser zwar tatsächlich jede sekunde ausgelöst (Interval ist 1000) jedoch wird die variable, die eigentlich bei jedem aufruf nur um eins erhöht werden soll, um zwei oder sogar 3 erhöht (und das jede sekunde)!

kann mir jemand diese unregelmäßigkeit erklären? der timer wird doch korrekt aufgerufen oder? warum wird der wert der variable nicht richtig erhöht?
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Mo 06.02.06 23:14 
Also ich hab Dein Code oben mal überprüft und es ausprobiert. Bei mir funktioniert das einwandfrei. Wie hast Du denn festgestellt, dass die Variable um mehr als 1 erhöht wird? Mit dem Debugger?

Und wieso nimmst Du nicht die Systemzeit als "Taktgeber", wie ich es Dir oben geschildert habe?
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Mo 06.02.06 23:57 
Ich habe auch dieses Timer-Problem. Probiert es mal aus: Setzt einen Timer auf das Form, der z.b. einen Wert erhöht und ins MouseMove des Forms ein Sleep(10). Solange man die Maus bewegt wird das TimerEvent nie gefeuert.
Amateur
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 777

(Win98, WinMe) WinXP Prof
D3 Prof, D6 Pers, D2k5 Pers., Turbo C++ Explorer
BeitragVerfasst: Di 07.02.06 00:55 
ja vielleicht weil sleep den hauptthread komplett lahm legt und damit auch den timer.. also entweder sleep und nen extra timer thread oder anstatt sleep nen delay selbst schreiben und zwar mit application.processmessages...

_________________
"Kein dummes Gerede. Kein Rumrätseln. Denkt an nichts anderes mehr, nur noch an das, was vor euch liegt. Das ist die wahre Herausforderung. Ihr müßt euch vor euch selbst schützen, Leute." (Rennes in "Cube")
Beiträge: >700
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Di 07.02.06 02:05 
Aber nach dem Sleep werden wieder Messages verarbeitet bzw. an das Form geschickt, wie z.B. die Mausbewegung. Es wird jedoch nie eine Message an den Timer geschickt.
King_Crasher
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37

WIN XP
Delphi 2003
BeitragVerfasst: Di 07.02.06 11:52 
Der folgende Quelltext zeigt die Systemuhr an:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  DateTime : TDateTime;
  str : string;
begin
  DateTime := Time;  
  str := TimeToStr(DateTime); 
  Caption := str; // Anstatt "Caption" einfach den Ort eintragen wo du die Zeit hin haben                        willst//
BigBasti Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 45

Win XP
D7
BeitragVerfasst: Mi 08.02.06 11:06 
ich möchte es nicht mit der systemzeit machen, da bei ich etwas aus der zeit auslesen muss und (siehe oben) die minuten in sekundenschritten und die stunden in minutenschritten vergehen sollen, wodurch die systemzeit unpraktisch ist, da ihre minutenschritte logischerweise bis 60 gehen, ich aber diese nur bis 24 laufen lassen möchte. klingt veriwirrend, daher das schema was ich meine:

die systemzeit gibt aus:

04:12:45 (in Stunden/Minuten/Sekundenschritten)
Stunde:Minute:Sekunde

ich möchte das ganze so haben:

12:45 (in Minuten/Sekundenschritten)
Stunde:Minute (deshalb soll der erste wert, der sich ja im minutentakt erhöht, nur bis 24 gehen können)


ich hoffe aus meinen aufzeichnungen wird jemand schlau
Basti
digi_c
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1905

W98, XP
D7 PE, Lazarus, WinAVR
BeitragVerfasst: Mi 08.02.06 11:49 
Schau mal in die DtaeUtils Unit dort sind schöne Befehle zum auseinanderpflücken z.B. Dayof(),DecodeXYZ...
azubi_20
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 593

WinXP SP2, Ubuntu 8.4
D7 Enterp., D2005 Prof., Java (Eclipse 3.4.0)
BeitragVerfasst: Mi 08.02.06 11:51 
Also, hier eine Lösung mit einem sicheren Zähler (weil von Systemzeit abgeleitet) :

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:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
 { Private-Deklarationen }
private
    procedure init;

//...


var
//...
  std,
  min,
  sec,
  msec  : Word;
  zeit  : TDateTime;
  insec : LongInt;
  sichererZaehler : LongInt;
  vtime :TDateTime;
  initsec : LongInt;

//...

procedure TForm1.init;
begin
// Zähler wird zurückgesetzt
  vtime := Now;
  DecodeTime(vtime, std, min, sec, msec);
  initsec := std * 3600 + min * 60 + sec;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
DecodeTime(Now, std, min, sec, msec);
insec := std*3600 +min*60 +sec;

sichererZaehler := insec-initsec-1;

uhrlabel.Caption := inttostr(sichererZaehler div 60)+' : '+inttostr(sichererZaehler mod 60);

if uhrlabel.Caption = '23 : 59' then init;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
// Uhrzeitanzeige wird gestartet
   init;
   timer1.Enabled := true;
end;
BigBasti Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 45

Win XP
D7
BeitragVerfasst: Do 09.02.06 08:35 
damit sollte es klappen, danke! :-D

ich probiers mal aus und wenn es funktioniert, sag ich bescheid.