Du hast da wohl einen schnelleren Rechner als ich.
Zu Deinem
: Ja, Du gehst recht in der Annahme.
Mess' bitte noch einmal, aber mit anderen Bedingungen.
Setze die Priorität der Uhr (im Taskmanager) mal auf den niedrigstmöglichen Wert.
Starte einen anderen Prozess (oder mehrere), von denen Du weißt, das richtig Systemlast erzeugt wird, setze deren Priorität eventuell auf Hoch, bei Echtzeit kann es sein, dass Du Windows nicht mehr so recht bedienen kannst. Prüfe dann, ob die Uhr weiterhin genau geht.
Deine obige Berechnung ist genau das, was ich meine. Bei meinem Rechner müsste zwei- bis dreimal pro Minute das Intervall auf 999 gesetzt werden.
Unabhängig von den Messerergebnissen:
Wenn Du das Intervall immer neu berechnest, kommt bei der Berechnung halt (fast) immer 1000 heraus, dann wird eben das Intervall (fast) immer auf 1000 gesetzt, macht nix. Sollte aber mal (irgendwann im Laufe des Jahres) aus welchem Grund auch immer, die Uhr etwas nachgehen, dann korrigiert sie sich eben halt dann bei der Berechnung des Intervalls zur nächsten Sekunde.
Die Schaltsekunde von vor Kurzem hätte sie so auch automatisch korrigieren können. Auch eine beliebige Umstellung der Systemuhr (um Sekundenbruchteile) würde sie so automatisch korrigieren.
Sagen wir mal so: Wenn Du hier in Deinen Quelltext noch meine Routine von oben einbaust
Delphi-Quellcode:
QueryPerformanceCounter(endTime);
timer2.Interval := CalcTimerInterval(iOneSecond);
timer2.Enabled:=true;
ShowMessage('Die Routine benötigte etwa ' + IntToStr((endTime - startTime) * 1000 div freq) + ' ms');
bin ich schon zufrieden.
Um zu prüfen, ob dies auch wirklich geht, setze die Aktuallisierungszeit mal auf die volle Minute und schau dann, ob die Zeitangabe immer HH:MM:00,000 (+/- 1 MS) ist.
Als Chromleiste:
Baue, wenn Du mit dem bisherigen klargekommen bist und das zu
Deiner Zufriedenheit funktioniert, mal einen Nachfahren von TTimer, der, beim Setzen von Enabled := True, automatisch das Intervall auf die nötige Anzahl von Millisekunden bis zur nächsten vollen Sekunde setzt.
Ein von mir gebauter TTimer-Nachfahre hat u. a. folgende Attribute:
Delphi-Quellcode:
// Zu jeder vollen Sekunde (HH:MM:00,000, HH:MM:01,000, HH:MM:02,000, ...)
property OneSecond : Boolean read GetOneSecond Write SetOneSecond default False;
// Alle fünf Sekunden (HH:MM:00,000, HH:MM:05,000, HH:MM:10,000, ...)
property FiveSeconds : Boolean read GetFiveSeconds Write SetFiveSeconds default False;
// Alle fünfzehn Sekunden (HH:MM:00,000, HH:MM:15,000, HH:MM:30,000, ...)
property FifteenSeconds : Boolean read GetFifteenSeconds Write SetFifteenSeconds default False;
// Jede volle Minute (HH:01:00,000, HH:02:00,00, HH:03:00,000 ...)
property OneMinute : Boolean read GetOneMinute Write SetOneMinute default False;
// Jede vollen fünf Minuten (HH:00:00,000, HH:05:00,000, HH:10:00,000, ...)
property FiveMinutes : Boolean read GetFiveMinutes Write SetFiveMinutes default False;
// Jede vollen fünfzehn Minuten (HH:00:00,000, HH:15:00,000, HH:30:00,000, ...)
property FifteenMinutes : Boolean read GetFifteenMinutes Write SetFifteenMinutes default False;
// Jede volle Stunde (01:00:00,000, 02:00:00,000, 03:00:00,000 ...)
property OneHour : Boolean read GetOneHour Write SetOneHour default False;
// Um Mitternacht (00:00:00,000)
property Midnight : Boolean read GetMidnight Write SetMidnight default False;
property Enabled : Boolean read GetEnabled Write SetEnabled default False;
property Interval : Cardinal read GetInterval Write SetInterval default 1000;
property OnTimer : TNotifyEvent read fOnTimer Write SetOnTimer;
Sie dienen dazu, wenn einer der boolschen Werte gesetzt ist, wird das Timerereignis zu exakt diesem Zeitpunkt ausgelöst. Es kann (neben Enabled) immer nur einer der Werte auf True stehen. Die Änderung eines der Werte setzt die anderen automatisch auf False. Das Setzen von Enabled auf True berechnet automatisch für das Intervall die benötigte Anzahl von Millisekunden bis zum Eintreten dieses Zeitpunktes, ist keiner der boolschen Werte gesetzt, so wird das Intervall unverändert belassen, es bleibt also die Funktionälität des Vorfahrens TTimer erhalten.