Uzyskanie "globalnej" pozycji myszy w Mac OS X

Jak mogę dostać się w Mac OS X "globalna" pozycja myszy - chodzi mi o to, jak Mogę w cocoa/cf/whatever znaleźć pozycję kursora, nawet jeśli jest poza oknem, a nawet jeśli moje okno jest nieaktywne?

Wiem, że jest to jakoś możliwe (nawet bez uprawnień admina), bo widziałem coś takiego w Javie - ale chcę to napisać w ObjC

Przepraszam za mój angielski-mam nadzieję, że zrozumiesz o co mi chodzi;)

Author: radex, 2010-02-14

5 answers

NSPoint mouseLoc;
mouseLoc = [NSEvent mouseLocation]; //get current mouse position
NSLog(@"Mouse location: %f %f", mouseLoc.x, mouseLoc.y);

Jeśli chcesz, aby stale dostawał współrzędne, upewnij się, że masz NSTimer lub coś podobnego

 30
Author: Matt S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-14 20:00:43

Matt S. ma rację, że jeśli można użyć NSEvent API, aby uzyskać lokalizację myszy. Jednak nie trzeba ankiety, aby stale uzyskać współrzędne. Możesz zamiast tego użyć CGEventTap:

- (void) startEventTap {
    //eventTap is an ivar on this class of type CFMachPortRef
    eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, kCGEventMaskForAllEvents, myCGEventCallback, NULL);
    CGEventTapEnable(eventTap, true);
}

CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
    if (type == kCGEventMouseMoved) {
        NSLog(@"%@", NSStringFromPoint([NSEvent mouseLocation]));
    }

    return event;
}

W ten sposób twoja funkcja myCGEventCallback będzie strzelać za każdym razem, gdy mysz się poruszy (niezależnie od tego, czy Twoja aplikacja jest przednia, czy nie), bez konieczności ankiety na informacje. Nie zapomnij CGEventTapEnable(eventTap, false) i CFRelease(eventTap) Kiedy skończysz.

 29
Author: Dave DeLong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-14 20:13:01

Jeśli nie jesteś w kakaowej krainie i dotknięcie zdarzenia nie jest odpowiednie dla sytuacji,

CGEventRef event = CGEventCreate(nil);
CGPoint loc = CGEventGetLocation(event);
CFRelease(event);
Działa.
 6
Author: Jon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-16 14:52:19

Matt ma rację, ale w celu ciągłego uzyskiwania współrzędnych, uważam, że inną opcją jest użycie monitora zdarzeń dostarczonego przez NSEvent. Spróbuj addGlobalMonitorForEventsMatchingMask:handler: i addLocalMonitorForEventsMatchingMask:handler:. Sprawdź odniesienie do klasy NSEvent , aby uzyskać więcej szczegółów.

 3
Author: xdai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-05 05:43:44

Dla ciągłej aktualizacji globalnej pozycji kursora, oto jak wygląda kod (Swift 4.0.3):

override func viewDidLoad()
{
    super.viewDidLoad()

    NSEvent.addGlobalMonitorForEvents(matching: NSEvent.EventTypeMask.mouseMoved, handler: {(mouseEvent:NSEvent) in
        let position = mouseEvent.locationInWindow
    })
}

Uwaga, zmienna "position" jest obiektem NSPoint o współrzędnych x i y (wśród wielu innych atrybutów). Nie zwróci to współrzędnych, jeśli aplikacja jest w centrum uwagi lub gdy klikasz i przeciągasz. Istnieją osobne zdarzenia dla wszystkich z nich: po prostu zmień nsevent.EventTypeMask.mouseMoved to a different EventTypeMask

 0
Author: Smitty-Werben-Jager-Manjenson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-02 00:53:29