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/)
-   -   Auto logout nach Zeit (https://www.delphipraxis.net/210337-auto-logout-nach-zeit.html)

norwegen60 7. Apr 2022 14:25

Auto logout nach Zeit
 
Hallo zusammen,

mit
Delphi-Quellcode:
Application.OnMessage
ist es recht einfach, einen Timer zurück zu setzen sobald Tastatur oder Maus betätigt wurde. Das funktioniert aber nur, wenn diese Änderung innerhalb meiner Anwendung passiert.

Wie kann ich Maus- oder Tastatur-Ereignisse erfassen, wenn die außerhalb meiner Anwednung auftreten? Kann sein, weil meine Anwendung nur ein Teil es Bildschirms einnimmt oder weil z.B. Office davor geöffnet wurde.

Grüße
Gerd

sakura 7. Apr 2022 14:37

AW: Auto logout nach Zeit
 
Ich beantworte jetzt nicht unbedingt Deine Frage, würde aber empfehlen nicht auf diese Art und Weise die Aktivität des Nutzers zu testen, dass kann dieser über die Winodws-Funktion "Automatisches Sperren". Eher würde ich empfehlen zu reagieren, wenn der Nutzer eine Funktion im Programm ausführt und dann die Session zu verlängern. Wenn das Programm nicht genutzt wird, dann läuft die Session in Ruhe ab.

...:cat:...

Der schöne Günther 7. Apr 2022 17:53

AW: Auto logout nach Zeit
 
Ohne dein genaues Anwendungsszenario zu kennen:

Es gibt unter Windows die Methode GetLastInputInfo(..)

Als Delphi verpackt sieht das bei uns so aus:

Delphi-Quellcode:
uses System.TimeSpan, System.SysUtils, Winapi.Windows;

function TTimes.getSinceLastInput(): TTimeSpan;
var
   lastInput: TLastInputInfo;
   currentTickCount: DWORD;
   millisecondsPassed: Double;
begin
   lastInput := Default(TLastInputInfo);
   lastInput.cbSize := SizeOf(TLastInputInfo);

   Win32Check( GetLastInputInfo(lastInput) );
   currentTickCount := GetTickCount();

   // lastInput was before 49.7 days but by now, 49.7 days have passed
   if (lastInput.dwTime > currentTickCount) then
      begin
         millisecondsPassed :=
            (DWORD.MaxValue - lastInput.dwTime)
            +
            (currentTickCount * 1.0); // cast to float by multiplying to avoid DWORD overflow
         Result := TTimeSpan.FromMilliseconds(millisecondsPassed);
      end
   else
      Result := TTimeSpan.FromMilliseconds(currentTickCount - lastInput.dwTime );
end;

HolgerX 7. Apr 2022 19:22

AW: Auto logout nach Zeit
 
Hmm..

Wenn Du auf Tastendruck oder Mausbewegung reagieren willst, welche außerhalb deiner App erfolgen, dann wirst Du nicht um einen Low-Level Hook herum kommen....
In einer Schleife/Timer den letzten Tastendruck abzufragen ist unschön ;)


Hier mal ein Schnipsel:

Delphi-Quellcode:
type
  tagKBDLLHOOKSTRUCT = record
    vkCode: DWORD;
    scanCode: DWORD;
    flags: DWORD;
    time: DWORD;
    dwExtraInfo: DWORD;
  end;
  TKbdDLLHookStruct = tagKBDLLHOOKSTRUCT;
  PKbdDLLHookStruct = ^TKbdDLLHookStruct;

var
  HookHandle : HHOOK;
  WindowHandle : Hwnd;

function LowLevelKeyboardProc(nCode: Integer; wParam: wParam;
    lParam: lParam): LRESULT; stdcall;
  var vkCode: Cardinal;
begin
  if (nCode >= 0) and (wParam = WM_KEYDOWN) then
  begin
    vkCode := PKbdDLLHookStruct(lParam)^.vkCode;
    Form1.Memo1.Lines.Add('vkCode ' + IntToStr(PKbdDLLHookStruct(lParam)^.vkCode));
    Form1.Memo1.Lines.Add('scanCode ' + IntToStr(PKbdDLLHookStruct(lParam)^.scanCode));
    Form1.Memo1.Lines.Add('flags ' + IntToStr(PKbdDLLHookStruct(lParam)^.flags));
    Form1.Memo1.Lines.Add('time ' + IntToStr(PKbdDLLHookStruct(lParam)^.time));
    Form1.Memo1.Lines.Add('dwExtraInfo ' + IntToStr(PKbdDLLHookStruct(lParam)^.dwExtraInfo));
    // meine Anweisungen
    PostMessage(WindowHandle, WM_SYSKEYDOWN, vkCode, lParam);

  end;
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;

function InstallHook(Hwnd: Cardinal): Boolean;
begin
  Result := False;
  if HookHandle = 0 then
  begin
    HookHandle := SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);
    WindowHandle := Hwnd;
    Result := HookHandle <> 0;
  end;
end;

function UninstallHook: Boolean;
begin
  Result := UnhookWindowsHookEx(HookHandle);
  HookHandle := 0;
end;

Der schöne Günther 7. Apr 2022 21:19

AW: Auto logout nach Zeit
 
Man braucht keinen LowLevel-Hook, das eins weiter oben angesprochene GetLastInputInfo(..) ist ausreichend.

norwegen60 7. Apr 2022 22:15

AW: Auto logout nach Zeit
 
Die Lösung von Günter erfüllt genau das was ich gesucht habe. Vielen Dank dafür.

Eine Frage hätte ich aber noch. Was führt denn alles dazu, dass die Idle time wieder zurück gesetzt wird. Ich hatte z.B. mal eine Maus, die je nach Lage gezittert hat. Das konnte ich in OnMessage abfangen, indem ich die Bewegung von 1 Pixel auf 5 erhöht habe.

Der schöne Günther 8. Apr 2022 07:48

AW: Auto logout nach Zeit
 
Input ist Input. Wenn du jetzt dir jeden Input genau anschauen und auf Plausibilität prüfen möchtest, dann ist der angesprochene Low Level-Hook wohl doch etwas für dich 😉


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:09 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