Laden...

Mausklick Programmweit abfragen (bzw. Event auslösen)

Erstellt von steffen_dec vor 16 Jahren Letzter Beitrag vor 16 Jahren 8.234 Views
S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 16 Jahren
Mausklick Programmweit abfragen (bzw. Event auslösen)

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

915 Beiträge seit 2006
vor 16 Jahren

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(

B
142 Beiträge seit 2007
vor 16 Jahren

Hm wenn das nur Programmintern ist, reicht dann nicht ein MouseDown Event zu definieren?

MfG
Björn

915 Beiträge seit 2006
vor 16 Jahren

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(

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 16 Jahren

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

915 Beiträge seit 2006
vor 16 Jahren

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(

S
steffen_dec Themenstarter:in
322 Beiträge seit 2007
vor 16 Jahren

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 👍

915 Beiträge seit 2006
vor 16 Jahren

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(

B
142 Beiträge seit 2007
vor 16 Jahren

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?