Hallo Leute,
ich möchte in meinem Programm eine AutoLogout Funktion einbauen. D.h. der Benutzer wird automatisch nach Ablauf einer definierten Zeit ausgeloggt.
Sobald der Benutzer irgendeine Taste drückt (Tastatur oder Maus) soll sich die Zeit wieder zurücksetzen.
Das mit der Tastatur habe ich nun drin. Mir fehlen jetzt nur noch Mausklicks.
Wie kann man Mausklicks Programmweit (also nur in meinem Programm, aber auf allen controls, menüs usw.) überwachen? Ich möchte praktisch bei jedem Mausklick den Timer zurücksetzen.
Über die Suche habe ich leider nichts finden können.
Vielen Dank im Voraus.
Steffen
Es gibt dafür mehrere Möglichkeiten.
Hast du eine Hauptform als Container für deine anderen Forms, so kannst du das in der WndProc der HauptForm abfangen.
Ansonsten kannst du über die ProcessId einen globalen MouseHook auf deine Application schreiben. Siehe dazu LowLevelHook Windows API oder eben www.pinvoke.net MouseHook.
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
Hm wenn das nur Programmintern ist, reicht dann nicht ein MouseDown Event zu definieren?
MfG
Björn
Original von Björn
Hm wenn das nur Programmintern ist, reicht dann nicht ein MouseDown Event zu definieren?MfG
Björn
Wenn er nur eine Form benutzt hast du natürlich recht mit protected override void OnMouseDown(MouseEventArgs e) den Timer Stoppen bzw neu starten.
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
Wenn er nur eine Form benutzt hast du natürlich recht mit protected override void OnMouseDown(MouseEventArgs e) den Timer Stoppen bzw neu starten.
Hallo,
werden dann auch die Klicks die ich auf Controls tätige abgefangen? (z.b. Button oder Tabstrip...)
ich benutze vorerst nur eine form.
würde es dann so aussehen?
protected override void OnMouseDown(MouseEventArgs e)
{
if (timerLogout.Enabled)
{
timerLogout.Stop();
timerLogout.Start();
}
}
werden die Klicks dann dennoch weitergeleitet und ggf. verarbeitet? oder werden diese geschluckt? Wenn ja, wie leitet man diese weiter an das system? (base.OnMouseDown(e) oder wie?)
ich habe im programm schon ein keyboardhook eingebaut
Danke
Steffen
Nein werden sie nicht. Gib mir einen Moment und ich poste dir die Lösung dazu.
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
ja genau dass habe ich gerade auch festgestellt... wenn man nicht direkt auf die form klickt, werden die klicks nicht abgefangen oder erkannt.
ich danke dir schon mal! nett von dir 👍
Also dieser "globale" Hook.
Dieser reagiert immer auf deinem gesamten Thread!
GUI's die z.B in anderen Threads laufen musst dann nur den Hook Anpassen, statt GetCurrentThreadId dann eben die GetCurrentProzessId mitgeben und die GetCurrentThreadId auf 0 belassen.
Denke mal das wars was gesucht hattest.
public partial class Form1 : Form
{
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(HookType code, HookProc func, IntPtr hInstance, int threadID);
[DllImport("user32.dll")]
private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
private HookProc myCallbackDelegate = null;
public enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
public Form1()
{
InitializeComponent();
// initialize our delegate
this.myCallbackDelegate = new HookProc(this.MyCallbackFunction);
// setup a global gui-thread mouse hook
SetWindowsHookEx(HookType.WH_MOUSE, this.myCallbackDelegate, IntPtr.Zero, AppDomain.GetCurrentThreadId());
}
private enum MMsg : int
{
HC_ACTION = 0,
WH_MOUSE_LL = 14,
WM_MOUSEMOVE = 0x200,
WM_LBUTTONDOWN = 0x201,
WM_LBUTTONUP = 0x202,
WM_LBUTTONDBLCLK = 0x203,
WM_RBUTTONDOWN = 0x204,
WM_RBUTTONUP = 0x205,
WM_RBUTTONDBLCLK = 0x206,
WM_MBUTTONDOWN = 0x207,
WM_MBUTTONUP = 0x208,
WM_MBUTTONDBLCLK = 0x209,
WM_MOUSEWHEEL = 0x20A,
}
private int MyCallbackFunction(int code, IntPtr wParam, IntPtr lParam)
{
if (code < 0)return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
MMsg buttonPressed = (MMsg)wParam.ToInt32();
if (buttonPressed == MMsg.WM_LBUTTONDOWN) // usw..
{
Console.WriteLine("Left mouse down");
// hier dann dein: Ende + Start vom Timer
}
//return the value returned by CallNextHookEx
return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}
}
Wenn du die Mousepositionen noch brauchst kannst den LParam mit Marshal.PtrToStructure in das MOUSEHOOKSTRUCT umwandeln (befindet sich in der MS Platform SDK). Aber ich denke möchtest ja nur nen Timer Starten und Stoppen, da reicht das.
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
Tut mir leid, dass es nur in der Form abgefangen wird, hatte ich nicht bedacht.
Nur mal der vollständigkeit halber, wie hast du es mit den Tastendruck gemacht?
Müsste ja im Prinzip auch nen Hook sein oder nicht?