Laden...

Globaler MouseHook mit WH_MOUSE_LL

Erstellt von -Hades- vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.611 Views
-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren
Globaler MouseHook mit WH_MOUSE_LL

Hi,

ich möchte global Mouseevents abfangen und benutze dazu WH_MOUSE_LL aber irgendwo scheint der Wurm drin zu sein, da meine HookProcedure gar nicht augerufen wird wie es scheint. Ich hoffe jemand kann mir da weiterhelfen, ich bin in der Thematik noch ziemlicher Neuling.

Hier mein Code (ich rufe an anderer Stelle den Konstruktor von Intercept_Mouse auf, wodurch HookCallBack ja an sich in die Kette eingereiht werden sollte) und ja ich weiß das ich noch Unhook aufrufen muss weil mein System sonst langsam wird und ich mit anderen Prozessen Probleme bekommen kann aber ich denke das wird dann nicht mehr das Problem sein.


    class Intercept_Mouse
    {
        private static LowLevelMouseProc _proc = HookCallback;
        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
        private static IntPtr _hookID = IntPtr.Zero;


        public Intercept_Mouse()
        {
            _hookID = SetWindowsHookEx(WH_MOUSE_LL, _proc, IntPtr.Zero, 0);
        }

        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && (MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam))
            {
                Console.WriteLine("Geklickt");
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }


        private const int WH_MOUSE_LL = 14;

        private enum MouseMessages
        {
            WM_LBUTTONDOWN = 0x0201,
            WM_LBUTTONUP = 0x0202,
            WM_MOUSEMOVE = 0x0200,
            WM_MOUSEWHEEL = 0x020A,
            WM_RBUTTONDOWN = 0x0204,
            WM_RBUTTONUP = 0x0205
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct POINT
        {
            public int x;
            public int y;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
    }

Gruß und Dank Hades

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Weiß denn niemand was ich da falsch mache? Ich finde den Fehler einfach nicht, womöglich habe ich da auch etwas ganz falsch verstanden, ich bin für jede Hilfe dankbar.

915 Beiträge seit 2006
vor 15 Jahren

Hallo -hades-

Du hast das MSLLHOOKSTRUCT zwar drinnen aber verwendest es nicht 🙂


public delegate int mouseHookProc(int code, int wParam, ref MSLLHOOKSTRUCT lParam);

[DllImport("user32.dll")]
public static extern IntPtr SetWindowsHookEx(int idHook, mouseHookProc callback, IntPtr hInstance, uint threadId);

private int HookProc(int code, int wParam, ref Win32.MSLLHOOKSTRUCT lParam)
        {
            if (code >= 0)
            {
              usw..
            }
            return Win32.CallNextHookEx(this.m_hHook, code, wParam, ref lParam);
        }


Für den globalen Aufruf gibt es nun verschiedene Ansätze, ich verwende diesen hier wenn es global sein soll, wenn dein aufruf nur auf deinen Thread (GUi Thread) oder nur auf einer speziellen form laufen soll, melde dich nochmal.

Hier der globale Mousehook:


  private void InitHook()
        {
            this.HookProcHandler = new Win32.mouseHookProc(this.HookProc);
            this.m_hInstance = Win32.LoadLibrary("User32");
            this.m_hHook = Win32.SetWindowsHookEx(Win32.WH_MOUSE_LL, this.HookProcHandler, this.m_hInstance, 0);
        }

private void UnHook()
        {
            this.HookProcHandler = null;
            Win32.FreeLibrary(this.m_hInstance);
            Win32.UnhookWindowsHookEx(m_hHook);
        }

Natürlich musst den Code bei dir anpassen, wichtig ist hInstance. LoadLibrary, FreeLibrary und UnhookWindowsHookEx findest unter www.pinvoke.net

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

-
-Hades- Themenstarter:in
171 Beiträge seit 2007
vor 15 Jahren

Hi,

danke für die Antwort.
Ich habe die Lösung aber bereits. Mein Code funktioniert wohl, aber da ich direkt nach dem Setzen des Hooks eine Schleife aufrufe die auch recht lange läuft schmeißt Windows meinen Hook aus der Hook Chain raus. Klingt komisch, is aber so 😉 Davon steht auch nichts in der MSDN. Na ja, habs jetzt aber gelöst.

Gruß Hades