Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Realisierung Programm wurde gewisse Zeit nicht bedient ? (https://www.delphipraxis.net/157853-realisierung-programm-wurde-gewisse-zeit-nicht-bedient.html)

RalfE 27. Jan 2011 10:13

Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Hallo,

Delphi 7

Wie kann man in einem Delphi-Programm realisieren,
dass ein Programm vom Benutzer x-Stunden nicht benutzt(bedient) wurde ?

Zeit sollte einstellbar sein , nach dieser Zeit
der "Ruhe" sollte ein Ereignis ausgelöst werden.

Danke.

Gruss

Sir Rufo 27. Jan 2011 10:43

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Das kommt darauf an, wie man "nicht benutzen/bedient" für die Anwendung definiert

Schau dir mal Delphi-Referenz durchsuchenTApplicationEvents an, das feuert viele Events, anhand derer man das festmachen könnte.

Das IdleEvent kommt dann von einem Timer der auf der MainForm liegt (z.B. IdleTimer) mit dem gewünschten Intervall (z.B. 60000ms)

Den Timer bei einer Aktion so zurücksetzen:
Delphi-Quellcode:
IdleTimer.Enabled := False;
IdleTimer.Enabled := True;
Wenn das mit den ApplicationEvents nichts bringt, dann musst du bei jeder Aktion die du als "der Benutzer arbeitet mit meiner Anwendung" den Timer zurücksetzen.

himitsu 27. Jan 2011 10:54

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Es gibt zwei grudsätliche Möglichkeiten

- Du startest einen Timer mit dem "Timeout" und immer wenn der Benutzter was macht (bediehnt) startest du diesen Timer neu (Enable auf False und wieder auf True).
ist die Zeit abgelaufen löst der Timer nun seine Ereignismethode aus.

- Immer wenn der Benutzer etas macht, wird eine Variable auf die aktuelle Zeit gesetzt
und nebenbei läuft ein Timer Timer (z.B. mit einem Minutenintervall), worin wird die Zeit der letzen Bediehnung mit der aktuellen Zeit verglichen wird.
Ist die Zeit abgelaufen (Differentz groß genug, dann löst du das Ereignis aus.

Bummi 27. Jan 2011 12:09

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
eine elegante Version wurde hier vor einiger Zeit gepostet.
Delphi-Quellcode:
function LastInput: DWord;
var LInput: TLastInputInfo;
begin
  LInput.cbSize := SizeOf(TLastInputInfo);
  GetLastInputInfo(LInput);
  Result := GetTickCount - LInput.dwTime;
end;


procedure TForm2.Timer1Timer(Sender: TObject);
begin
   Caption := IntToStr(LastInput);
end;

himitsu 27. Jan 2011 12:44

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
MSDN-Library durchsuchenGetLastInputInfo gibt an, wann zuletzt Benutzereingaben im Windows eingingen.
Wenn man nun in einem anderem Programm was macht, dann wird das ja auch mitgezählt, wärend das eigene Programm schon seit Tagen untätig sein könnte.

Aber vielleicht reicht das ihm ja aus.

Deep-Sea 27. Jan 2011 12:53

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Eine weitere Möglichkeit (nicht ausführlich getestet):
Delphi-Quellcode:
var
  LastInputTime: DWord;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  Case Msg.Message of
    WM_KEYFIRST..WM_KEYLAST, WM_MOUSEFIRST..WM_MOUSELAST:
      If Msg.Message <> WM_MOUSEMOVE then LastInputTime := GetTickCount;
  end;
end;
Ob das nun so schlau ist, sich ins OnMessage-Event einzuklinken ... ka :-D

Bummi 27. Jan 2011 13:06

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
@himitsu
berechtigter Einwand, lässt sich aber berücksichtigen:
Delphi-Quellcode:
  public
    { Public-Deklarationen }
    FIdle:Dword;
    FLTC:Cardinal;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

function TForm2.LastInput: DWord;
var LInput: TLastInputInfo;
tc:Cardinal;
begin
  LInput.cbSize := SizeOf(TLastInputInfo);
  GetLastInputInfo(LInput);
  tc := GetTickCount;
  if FLTC=0 then FLTC := getTickCount;

  if Application.Active then
      FIdle := tc - LInput.dwTime
  else
    begin
    FIdle := FIdle + TC - FLTC ;
    end;
  FLTC := TC;
  Result := FIdle;
end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
    Caption := intToStr(LastInput);
end;

Assarbad 27. Jan 2011 13:36

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Es gibt echt noch Leute die MSDN-Library durchsuchenGetTickCount benutzen ohne sich der Tatsache bewußt zu sein daß Windowssysteme immer länger laufen und immer zuverlässiger werden? :shock:

alfold 27. Jan 2011 13:39

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
hi, lasst den TE doch erst mal auf die vielen Angebote antworten :wink:
Noch weiss ja keiner so richtig wie er dies meint?
Zitat:

Zitat von RalfE (Beitrag 1077592)
Hallo,
...dass ein Programm vom Benutzer x-Stunden nicht benutzt(bedient) wurde ?
....

Meint er nun sein Prog, oder evtl allg Programme in Windows?

Zumal sich ja hier auch die Frage aufwirft, das man eigtl wissen sollte, was man auf seinem Rechner noch alles selber gestartet hatt. Und wenn ich was anderes machen soll/muss, ich alles beende wenn ich den Platzt verlasse.
Da nützt mir auch nicht, das mir (m)ein Prog mitteilt, das ich x Stunden nix mehr am Prog/Rechner gemacht habe oder sogar den Rechner runterfährt(Datenverlust mit eingeschlossen :pale:)
Nur weil was auch immer mich daran hindern sollte, Programme die ich nicht mehr brauche auch zu beenden :stupid:

Gruss alfold

Assarbad 27. Jan 2011 13:43

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Übrigens, ist MSDN-Library durchsuchenWM_ENTERIDLE nicht auch ein gangbarer Weg? Könnte auch über einen Hook für andere Fenster abgefangen werden ...

RalfE 27. Jan 2011 15:11

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Hallo,

vielen dank für die Antworten.

Ist ein eigenes Programm, wird mit dem Programm
x Zeit nichts mehr gemacht (kein DB-Zugriff, kein Klicken
mehr...rein gar nichts), so soll über dieses Ereignis eine
Waage in Stand by geschaltet werden.

Wird immer vergessen....

Gruss

himitsu 27. Jan 2011 15:16

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
MSDN-Library durchsuchenGetTickCount macht in diesem Fall keinerlei Probleme, da MSDN-Library durchsuchenLASTINPUTINFO das selbe Format verwendet.

Es gäbe also nur Probleme, wenn der User 49,7 Tage lang nichts mehr am PC gemacht hat.

Und durch die Verwendung eines Ersatzes für GetTickCount läßt sich auch nichts verbessern, da LASTINPUTINFO dennoch beschränkt wäre.

alfold 27. Jan 2011 15:27

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Zitat:

Zitat von himitsu (Beitrag 1077672)
.....
Es gäbe also nur Probleme, wenn der User 49,7 Tage lang nichts mehr am PC gemacht hat.
....

Urlaub:-D

Ich denke mal das so lange sicherlich nicht gemeint ist und länger als ne halbe oder ganze Stunde he kaum in betracht kommt! Alles was schon länger ist, ist ja im betrieblichen Einsatz schon reine verschwendung!

Gruss alfold

Assarbad 27. Jan 2011 16:38

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Zitat:

Zitat von himitsu (Beitrag 1077672)
Es gäbe also nur Probleme, wenn der User 49,7 Tage lang nichts mehr am PC gemacht hat.

Unsinn. Es geht nicht darum wie lange der Benutzer etwas gemacht hat oder nicht sondern wie lange der Computer schon läuft. Wenn bei der Zeitabnahme an Punkt X und an Punkt X+Y der Wert überlief, haste trotzdem Mist als Ergebnis bei allen bisher abgelieferten Codebeispielen.

Zitat:

The tick count when the last input event was received.
Dort steht "when", nicht "since".

Der Überlauf kann an beliebiger Stelle kommen. Die Tatsache daß MSDN-Library durchsuchenLASTINPUTINFO es auch verwendet macht's eigentlich eher schlimmer, weil dann einfach dort das gleiche Problem dort auftritt.

Fazit: Ab Vista MSDN-Library durchsuchenGetTickCount64 statt GetTickCount verwenden oder Vorkehrungen treffen damit der Überlauf nicht alles versaut. Vorkehrungen müssen in jedem Fall bei MSDN-Library durchsuchenLASTINPUTINFO getroffen werden, weil es scheinbar kein 64bittiges Pendant gibt.

Deep-Sea 27. Jan 2011 16:42

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Zitat:

Zitat von Assarbad (Beitrag 1077700)
[...] haste trotzdem Mist als Ergebnis bei allen bisher abgelieferten Codebeispielen.

Nicht ganz. Kombiniert man mein Beispiel mit dem OnMessage-Event mit der Timer-Idee von Sir Rufo bzw. himitsu, dann ist es unabhängig von GetTickCount - sofern die Timer bei 50 Tage Dauerlauf noch arbeiten wie sie sollen :-D

Assarbad 27. Jan 2011 16:43

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Zitat:

Zitat von Deep-Sea (Beitrag 1077702)
[...] Timer-Idee [...]

Don't get me started :roll:

himitsu 27. Jan 2011 17:01

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Zitat:

Zitat von Assarbad (Beitrag 1077700)
Unsinn. Es geht nicht darum ...

Nicht?

LASTINPUTINFO = wann hatte der Benutzer zuletzt was gemacht (seit dem Systemstart aka Wert von GetTickCount)
GetTickCount = wie lange läuft das System schon

Bei der Differenzberechnung hat ein "Überlauf" in diesen Werten keine Auswirkung, solange beide Werte keine Differenz von mehr als die 47 Tage haben.

DeddyH 27. Jan 2011 17:25

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Ich mag mich täuschen, aber werden da nicht im worst case Äpfel mit Birnen verglichen?
GetTickCount -> Zeit seit dem Systemstart
GetLastInputInfo -> Zeit seit der letzten Benutzeraktion in der aktuellen Session

Es kann also sein, dass beim Einen ein Überlauf eintritt, beim Anderen aber nicht (sofern ich keinen groben Denkfehler mache).

Bummi 27. Jan 2011 17:46

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Delphi-Quellcode:
var
 c,d:cardinal;
 i:Integer;
 Procedure AddAndDisplay;
  begin
   c := c + 10;
   d := d + 10;
   Memo1.Lines.Add(IntToStr(c-d) + ' - ' + IntToStr(c) +  ' - ' + IntToStr(d));
  end;
begin
   c := 4294967290;
   d := c - 20;
   Memo1.Lines.Add(IntToStr(c-d) + ' - ' + IntToStr(c) +  ' - ' + IntToStr(d));
   for I := 0 to 10 do AddAndDisplay;
end;

Assarbad 27. Jan 2011 19:24

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Zitat:

Zitat von DeddyH (Beitrag 1077712)
Es kann also sein, dass beim Einen ein Überlauf eintritt, beim Anderen aber nicht (sofern ich keinen groben Denkfehler mache).

Genau um diese Möglichkeit geht es. Und genau deswegen kann der zweite Wert deutlich kleiner sein als der erste.

@Bummi: kein Delphi hier zur Hand. Demo des Überlauf's verstehe ich, aber ob dort das zu erwartende Ergebnis kommt, weiß ich erst nach Testlauf :zwinker:

Zitat:

Zitat von DeddyH (Beitrag 1077712)
GetLastInputInfo -> Zeit seit der letzten Benutzeraktion in der aktuellen Session

Eben nicht. Wert von GetTickCount zu dem Zeitpunkt als die letzte Benutzeraktion erfolgte. Nicht seit, sondern als.

Nachtrag:
Zitat:

Zitat von himitsu (Beitrag 1077706)
Bei der Differenzberechnung hat ein "Überlauf" in diesen Werten keine Auswirkung, solange beide Werte keine Differenz von mehr als die 47 Tage haben.

Nicht? Wir sind uns einig, daß $FFFFFFFF die 49,7 Tage sind, korrekt? Wir sind uns einig, daß der Benutzer 30min vor Überlauf ($FFFFF8F7) eine Aktion gemacht haben könnte? Wenn ich nun 35min nach der letzten Aktion GetTickCount aufrufe (= 5min nach Überlauf = $12C), sind wir uns auch einig, daß der Differenzwert die 35min (in Sekunde) betragen sollte, was weniger als 49,7 Tage ist ... richtig?

Nunja, dank Überlauf stimmt die Rechnung nun leider nicht mehr ganz. Denn $12C - $FFFFF8F7 ... und das alles ohne Vorzeichen kann ziemlichen Quark hervorbringen ;)

Soo, 1s Abweichung in den obigen Rechnungen mögen mir gestattet sein :mrgreen:

Deep-Sea 27. Jan 2011 20:03

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
a) GetTickCount gibt die Werte in Millisekunden zurück, somit sind 5 Minuten eigentlich $000493E0. Wäre es in Sekunden, würde es weit über 100 Jahre reichen (siehe Unix-Timestamp).

b) Aber bleiben wir mal beim Seundentakt:
$012C - $FFFFF8F7 = $0835 = 2101 Sekunden = 35 Minuten - und das ist doch richtig, oder habe ich da was falsch verstanden? :stupid:

himitsu 27. Jan 2011 20:12

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
LASTINPUTINFO = $FFFF8AD0 (30s vor Überlauf)
GetTickCount = $00007530 (30s nach Überlauf)


$00007530 - $FFFF8AD0 = $0000EA60 (60s)

Man muß nur beim Rechnen aufpassen, daß man natürlich unsigned (Cardinal) rechnet, damit der Überlauf korrekt behandelt wird. :stupid:

Wobei es hier zufällig signed auch mal paßt.
30 - -30 = 60


[add]
@Deep-Sea: nee, hast'e nicht :D

Assarbad 27. Jan 2011 20:15

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Zitat:

Zitat von Deep-Sea (Beitrag 1077757)
a) GetTickCount gibt die Werte in Millisekunden zurück, somit sind 5 Minuten eigentlich $000493E0. Wäre es in Sekunden, würde es weit über 100 Jahre reichen (siehe Unix-Timestamp).

Sorry, mein Fehler. Arbeite zuviel mit unixoiden Systemen. Denkt es euch einfach "korrekt" :lol:

Zitat:

Zitat von himitsu (Beitrag 1077759)
Man muß nur beim Rechnen aufpassen, daß man natürlich unsigned (Cardinal) rechnet, damit der Überlauf korrekt behandelt wird. :stupid:

Hast recht. Da liegt der Hase begraben. Breiterer Typ oder vorzeichenbehaftet wären problematisch, nur ohne Vorzeichen scheint wohl zu gehen.

alfold 27. Jan 2011 22:13

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Bei aller Begeisterung und Beteiligung von euch.
Die Frgae die ich mir stelle ist, wird die Waage über einen Rechner gesteuert und gibt sie über einer Schnittstelle die Daten, oder ist das eine Kassenwaage oder oder oder...?

Im ersteren muss man ja nur die Schnittstelle abfragen(wenn es erlaubt wird) ob da was passiert, wenn nicht dann Standby senden(aber Vorsicht Daten).

Also bleibt doch wohl erstmal die Frage, was es genau ist und wie das ganze Arbeitet, bevor man sich an sowas ranwagt :!:

Und dann kann man sehen ob man den Rechner abfragt die Schnittstelle oder sogar die Software.

Gruss alfold

RalfE 28. Jan 2011 07:37

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Guten Morgen,

die Waage ist dumm, es gibt ein ser. Kommando "gehe in Standby", die Kollegen vergessen immer wieder die Waage
über deren Bedienpult in diesen Modus zu schalten, deswegen sollte dies über den PC automatisiert werden. Wird mit dem Program solange nicht
gearbeitet, so schalte Waage in Stand by-Modus.
Auf dem Rechner laufen noch Office-Programme, die in der
Zwischenzeit von den Kollegen benutzt werden.

Gruss

mleyen 28. Jan 2011 08:14

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Messages, AppEvnts;

type
  TForm1 = class(TForm)
    tmr1: TTimer;
    aplctnvnts1: TApplicationEvents;
    procedure FormCreate(Sender: TObject);
    procedure tmr1Timer(Sender: TObject);
    procedure aplctnvnts1Message(var Msg: tagMSG; var Handled: Boolean);
  private
    FLastUserInput: Cardinal;
    FUserIsAfk: Boolean;
    function GetTimeSinceLastTick: Cardinal;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  UserIsAfkIn = 5000; // ms

procedure TForm1.aplctnvnts1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  case Msg.Message of
    WM_KEYFIRST..WM_KEYLAST, WM_MOUSEFIRST..WM_MOUSELAST:
      if Msg.Message <> WM_MOUSEMOVE then
        FLastUserInput := GetTickCount;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FLastUserInput := GetTickCount;
  FUserIsAfk := false;
  Caption := 'state green';
end;

function TForm1.GetTimeSinceLastTick: Cardinal;
begin
  if GetTickCount < FLastUserInput then
    Result := (High(Cardinal) - FLastUserInput) + GetTickCount
  else
    Result := GetTickCount - FLastUserInput;
end;

procedure TForm1.tmr1Timer(Sender: TObject);
begin
  if FUserIsAfk then
  begin
    if GetTimeSinceLastTick < UserIsAfkIn then
    begin
      Caption := 'User is back';
      FUserIsAfk := false;
    end;
  end
  else
  begin
    if GetTimeSinceLastTick >= UserIsAfkIn then
    begin
      Caption := '!!! Zomg! User stopped workin and idles around !!!';
      FUserIsAfk := true;
    end;
  end;
end;

end.
Gibts außer dem Timer noch etwas auszusetzen?

alfold 28. Jan 2011 10:45

AW: Realisierung Programm wurde gewisse Zeit nicht bedient ?
 
Zitat:

Zitat von mleyen (Beitrag 1077811)
[DELPHI]unit Unit1;
Gibts außer dem Timer noch etwas auszusetzen?

Im Prinzip schon!
Zitat:

Zitat von RalfE (Beitrag 1077800)
....Auf dem Rechner laufen noch Office-Programme, die in der
Zwischenzeit von den Kollegen benutzt werden.
Gruss

also geht es nicht mit der simplen abfrage ob Taste/Mouse nicht mehr benutzt wurden
Delphi-Quellcode:
case Msg.Message of
    WM_KEYFIRST..WM_KEYLAST, WM_MOUSEFIRST..WM_MOUSELAST:
      if Msg.Message <> WM_MOUSEMOVE then
        FLastUserInput := GetTickCount;
  end;
Darum ja auch die Frage von mir ob die Waage eine Schnittstelle hatt, welche?
Denn er muss ja den Befehl zur Waage schicken!
Nächste Frage ist, ob die Waage den 'Befehl Standby' von aussen überhaupt erkennt?
Nicht das es nur ne Hardware Angelegenheit ist! Dann hatt sich das Thema Software eh erledigt!

Wenn ja, dann fragt man nicht die Software ab (ob damit jemand arbeitet), sondern die Schnittstelle, ob da was passiert!

Solltest Du @RalfE erst mal Prüfen!

Gruss alfold


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz