![]() |
Windows-Benutzer-Leerlaufzeit
Ich möchte die Zeit wissen wie lang der Benutzer vor Ort keine Eingaben mehr vorgenommen hat (Touchscreen, Maus, Tastatur). Hier hilft einem die Windows-Routine
![]() Implementiert habe ich das bislang so:
Delphi-Quellcode:
Das Problem hierbei:
uses System.TimeSpan, WinApi.Windows;
function TTimes.getSinceLastInput(): TTimeSpan; var lastInput: TLastInputInfo; begin lastInput := Default(TLastInputInfo); lastInput.cbSize := SizeOf(TLastInputInfo); Win32Check( GetLastInputInfo(lastInput) ); Result := TTimeSpan.FromMilliseconds( GetTickCount64() - lastInput.dwTime ); end;
Delphi-Quellcode:
ist ein DWORD, reicht also nur für 49 Tage. Danach geht es wieder bei Null weiter.
lastInput.dwTime
Was ist hierbei die einfachste Lösung? Statt
Delphi-Quellcode:
einfach
GetTickCount64()
Delphi-Quellcode:
nehmen da er auch das "49 Tage-Problem" hat und sich beides wieder ausgleicht?
GetTickCount()
Mir geht es nur darum festzustellen ob länger als eine Zeitspanne X keine Eingaben mehr vorgenommen wurden. Da ist es auch nicht schlimm wenn es für ein paar Millisekunden während des Überlaufens nach 49 Tagen einmal falsch liegt. Bei der jetzigen Implementierung lieget er nach 49 Tagen immer falsch :| |
AW: Windows-Benutzer-Leerlaufzeit
GetTickCount <> GetTickCount64 hat rein garnichts mir GetLastInputInfo zu tun, bzw. GetLastInputInfo gibt es nur in einer Version, also egal.
GetTickCount und GetLastInputInfo nutzen zwar den seltem TimeStamp, aber dennoch kannst du das nicht mit GetTickCount64 kombinieren, da es dort keine Übereinstimmung gibt. 49 Tage lang ist bei euch keiner vorm PC? Wenn ja, dann lass doch einfach einmal am Tag einen Timer angehn. (oder einmal die Woche/pro Monat) Da schaust du dann, ob dein zuletzt gespeicherter TimeStamp mit GetLastInputInfo übereinstimmt. Wenn ja dann nichts machen und die gespeicherte Zeit nutzen. Wenn nein, dann die aktuelle Zeit minus die Offlinezeit (GetTickCount-GetLastInputInfo) rechnen und dir zusätzlich den aktuellen TimeStamp (GetLastInputInfo) speichern. > ändert sich GetLastInputInfo nicht, war keiner da ... bzw. in sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr seltenen Fällen war jemand ganz genau, auf die Millisekunde, nach 49.71026962962962962962962962963 Tagen erneut aktiv > und dein gespeicherter TimeStamp (nicht als TickCount, sondern als was Anderes ala TDateTime) ist noch gültig, egal wie alt > hat sich der TimeStamp (GetLastInputInfo) geändert, dann ist er nicht älter als wie dein Timer-Interval |
AW: Windows-Benutzer-Leerlaufzeit
Hallo Günther
wenn ich dich richtig verstehe, dann möchtest du Delta: = jetzt - letzteAktion auch dann berechnen können, wenn der "GetTickCount Zähler" nach dem Zeitpunkt letzteAktion wieder bei 0 startete. Wenn letzteAktion und jetzt weniger als High(Cardinal) Millisekunden (ca. 49 Tage) auseinanderliegen, dann könntest du es so tun:
Delphi-Quellcode:
function GetDeltaGTC( start : Cardinal ) : Cardinal;
var res, gtc : Cardinal; begin gtc := GetTickCount; if ( gtc >= start ) then Result := gtc - start else begin res := High(Cardinal)-start; res := res + gtc + 1; Result := res; end; end; |
AW: Windows-Benutzer-Leerlaufzeit
So aufwändig ist es garnicht nötig, wenn man mit Überläufen rechnet.
x := GetTickCount - LastUserInput; // oder sicherheitshalber immer mit Cast, wenn der implizite Cast durch due Zielvariable nicht ausreicht und wenn dich die Compilermeldungen stören x := Cardinal(GetTickCount - LastUserInput); |
AW: Windows-Benutzer-Leerlaufzeit
Vielen Dank für die Antworten, so werde ich es glaube ich machen: Einfach
Delphi-Quellcode:
gegen
GetTickCount64
Delphi-Quellcode:
tauschen (zumindest an dieser Stelle).
GetTickCount
Da könnte er nach genau 49.7 Tagen einmal kurz falsch liegen aber wen kümmert das 8-) |
AW: Windows-Benutzer-Leerlaufzeit
Zitat:
Delphi-Quellcode:
unangenehm, weil im Fall GetTickCount < LastUserInput eine Integerüberlauf-Exception ausgelöst (und x nicht berechnet) wird - und der Code beim Testen somit durchfällt.
x := GetTickCount - LastUserInput;
Bei ausgeschalteter Überlaufprüfung wird keine Exception ausgelöst und es wird "richtig" gerechnet. Zitat:
Delphi-Quellcode:
res=1
var a, b , res : cardinal;
begin a := high(cardinal); b := 0; res := b-a; |
AW: Windows-Benutzer-Leerlaufzeit
Ja. Das Integer-Exception-Problem sehe ich nicht auftreten, denn in meinem Fall ist die Variable x kein DWORD oder irgendein Unsigned-Typ sondern ein Double (Parameter von
Delphi-Quellcode:
) ;-)
TTimeSpan.FromMilliseconds(..)
|
AW: Windows-Benutzer-Leerlaufzeit
Hmm..
Mal eine Frage: Muss es überhaupt GetTickCount sein? Reichen nicht die Millisekunden von TDateTime? Mit Now die Startzeit vom Idle nehmen und dann kann mit MilliSecondsBetween die Differenz zum Ende von Idle ermittelt werden. Aufsummieren und schon haste die Gesamtzeit in ms. Für eine (einfache) Erfassung sollte dies auch ohne Überlauf ausreichen. |
AW: Windows-Benutzer-Leerlaufzeit
Woher soll ich wissen wann ich Now() aufrufen soll um den Zeitstempel zu aktualisieren und wann nicht? Das verstehe ich nicht.
GetLastInputInfo() liefert einen fertigen Zeitstempel wann jemand die aktuelle Windows-Sitzung das letzte mal bedient hat. Bis auf den Überlauf eigentlich schön einfach. |
AW: Windows-Benutzer-Leerlaufzeit
Ihr wisst aber, dass man die Überlaufprüfung um die Stelle mit dem Überlauf auch deaktivieren kann?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:58 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