2016-10-26 1 views
2

Ich versuche, einen Farbwähler zu implementieren, der die Farbe von einem Pixel überall auf dem Bildschirm nimmt. Dazu plane ich einen globalen Maus-Hook zu verwenden, um WM_MOUSEMOVE anzuhören, um die Farbe zu aktualisieren, während die Maus bewegt wird und Mausklicks zu hören, um die Operation zu bestätigen (WM_LBUTTONDOWN) oder abzubrechen (WM_RBUTTONDOWN).Maushaken wird getrennt

Ich habe eine der vielen Tutorials gefolgt um, und ich kam mit dieser (in einer Konsole-Anwendung, nur aus zu testen, ob der Prozess funktioniert):

static IntPtr hook; 
static bool click; 
static NativeMethods.LowLevelHookStruct llhs; 

static void Main(string[] args) 
{ 
    hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, MouseHookCallback, (IntPtr)null, 0); 
    if (hook != IntPtr.Zero) 
    { 
    Console.WriteLine("Hook Set"); 
    while (!Console.KeyAvailable) { 
     Console.WriteLine("{0} {1} {2}", hook, llhs.pt.x, llhs.pt.y); 

     if(click) Console.WriteLine("click!"); 
     click = false; 

     System.Threading.Thread.Sleep(250); 
    } 
    } 
} 

und

public static IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
{ 
    if (nCode >= 0) 
    { 
    NativeMethods.LowLevelHookStruct hookStruct = (NativeMethods.LowLevelHookStruct)Marshal.PtrToStructure(lParam, typeof(NativeMethods.LowLevelHookStruct)); 

    if (NativeMethods.MouseMessages.WM_MOUSEMOVE == (NativeMethods.MouseMessages)wParam) 
    { 
     llhs = hookStruct; 
    } 

    if (NativeMethods.MouseMessages.WM_LBUTTONDOWN == (NativeMethods.MouseMessages)wParam) 
    { 
     click = true; 
    } 
    else if (NativeMethods.MouseMessages.WM_RBUTTONDOWN == (NativeMethods.MouseMessages)wParam) 
    { 
    } 
    } 

    return NativeMethods.CallNextHookEx(hook, nCode, wParam, lParam); 
} 

NativeMethods ist einfach eine Klasse, in der ich alle DllImport-bezogenen Sachen aufbewahre.

Sobald ich die Konsole-Anwendung ausführen, wird der Mauszeiger für ein paar Sekunden stecken, und in der Konsole bekomme ich diese - auch während der Cursor

stecken ist
Hook Set 
3945554872 0 0 
3945554872 0 0 
3945554872 0 0 
3945554872 0 0 
... 

in debug es gehen Es scheint, dass mein Haken nie aufgerufen wird, nicht einmal. Irgendeine Idee, was könnte falsch sein?

+0

Ich habe ein Tag aus dem Titel Ihrer Frage entfernt. Bitte lesen Sie [hier] (http://stackoverflow.com/help/tagging) warum. – dymanoid

+0

Ah, habe es vergessen. Danke :) – SirePi

+1

Ein WH_MOUSE_LL-Hook benötigt eine Nachrichtenschleife, damit Windows den Hook-Callback sicher aufrufen kann. Application.Run() in einem .NET-Programm. Am leichtesten hatten Sie von einem Winforms- oder WPF-Projekt oder einer der vielen Bibliotheken, die das für Sie tun. –

Antwort

0

Im Anschluss an @Hans Passant Kommentar Ich habe meinen Testcode in eine WinForms-Anwendung verschoben, und Rückrufe kamen.

Dann war es nur eine Frage, um herauszufinden, dass der Rückruf Müll gesammelt wurde, so alles, was ich tun musste, war

hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, MouseHookCallback, (IntPtr)null, 0); 

zu

private NativeMethods.LowLevelHookProc _hookCallback; 

... 

_hookCallback = new NativeMethods.LowLevelHookProc(MouseHookCallback); 
hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, _hookCallback, (IntPtr)null, 0); 

, um ein zu halten zu ändern Referenz auf den Rückruf, so dass es nicht GCed wäre.

Verwandte Themen