2010-04-29 12 views
52

Ist es möglich, die Aktionen einer Maus aus einem Programm in OS X zu simulieren? Insbesondere versuche ich in der kurzen Version einen Touchscreen mit zwei Webcams zu simulieren. Unter der Annahme, dass ich X-, Y-Positionen erhalten kann, kann ich Informationen als Mausbewegung oder Klick an das Betriebssystem senden.Simulation der Mauseingabe programmgesteuert in OS X

Edit-Oder wenn es besonders einfach in einem anderen Betriebssystem ist, würde ich bereit sein, darüber nachzudenken.

+0

auf Ihren Anwendungsfall abhängig, gibt es eine Instrument namens "UI Recorder", das alles aufzeichnet, was Sie an der Benutzeroberfläche Ihres Programms machen, und es wiederholt, wenn Sie möchten. – zneak

+0

Danke, aber was ich wirklich möchte, ist das Senden beliebiger Mauseingaben an das Betriebssystem. –

+3

Ich habe dies zuvor durch Ausführen eines VNC-Servers und Schreiben eines kleinen VNC-Clients, um Mausereignisse an den Server zu senden. Es gibt Open-Source-VNC-Server, die das tun, also wäre ein nettes letztes Mittel, die Quelle eines zu lesen. –

Antwort

82

Ja, es ist möglich. Mit dem Quartz Event Services können Sie Eingangsereignisse simulieren.

C Unter der Annahme, ich schrieb dieses kurzes Beispiel:

#include <ApplicationServices/ApplicationServices.h> 
#include <unistd.h> 

int main() { 
    // Move to 200x200 
    CGEventRef move1 = CGEventCreateMouseEvent(
     NULL, kCGEventMouseMoved, 
     CGPointMake(200, 200), 
     kCGMouseButtonLeft // ignored 
    ); 
    // Move to 250x250 
    CGEventRef move2 = CGEventCreateMouseEvent(
     NULL, kCGEventMouseMoved, 
     CGPointMake(250, 250), 
     kCGMouseButtonLeft // ignored 
    ); 
    // Left button down at 250x250 
    CGEventRef click1_down = CGEventCreateMouseEvent(
     NULL, kCGEventLeftMouseDown, 
     CGPointMake(250, 250), 
     kCGMouseButtonLeft 
    ); 
    // Left button up at 250x250 
    CGEventRef click1_up = CGEventCreateMouseEvent(
     NULL, kCGEventLeftMouseUp, 
     CGPointMake(250, 250), 
     kCGMouseButtonLeft 
    ); 

    // Now, execute these events with an interval to make them noticeable 
    CGEventPost(kCGHIDEventTap, move1); 
    sleep(1); 
    CGEventPost(kCGHIDEventTap, move2); 
    sleep(1); 
    CGEventPost(kCGHIDEventTap, click1_down); 
    CGEventPost(kCGHIDEventTap, click1_up); 

    // Release the events 
    CFRelease(click1_up); 
    CFRelease(click1_down); 
    CFRelease(move2); 
    CFRelease(move1); 

    return 0; 
} 

Und GCC unter der Annahme, kompilieren mit:

gcc -o program program.c -Wall -framework ApplicationServices

genießen Sie die Magie.

+2

Whoa, große Antwort auf eine alte Frage, danke! –

+0

@Rob: Gern geschehen. Ich hoffe, die Antwort kam nicht zu spät. – jweyrich

+0

funktioniert wie ein Charme – piaChai

7

Wenn Sie nicht wollen, Dinge zu kompilieren und suchen nach einem Shell-basierten Tool, kann Cliclick die Lösung sein.

2

hier ein Arbeits C-Programm ist die Antwort basierend auf jweyrick suchen:

// Compile instructions: 
// 
// gcc -o click click.c -Wall -framework ApplicationServices 

#include <ApplicationServices/ApplicationServices.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) { 
    int x = 0, y = 0, n = 1; 
    float duration = 0.1; 

    if (argc < 3) { 
    printf("USAGE: click X Y [N] [DURATION]\n"); 
    exit(1); 
    } 

    x = atoi(argv[1]); 
    y = atoi(argv[2]); 

    if (argc >= 4) { 
    n = atoi(argv[3]); 
    } 

    if (argc >= 5) { 
    duration = atof(argv[4]); 
    } 

    CGEventRef click_down = CGEventCreateMouseEvent(
    NULL, kCGEventLeftMouseDown, 
    CGPointMake(x, y), 
    kCGMouseButtonLeft 
); 

    CGEventRef click_up = CGEventCreateMouseEvent(
    NULL, kCGEventLeftMouseUp, 
    CGPointMake(x, y), 
    kCGMouseButtonLeft 
); 

    // Now, execute these events with an interval to make them noticeable 
    for (int i = 0; i < n; i++) { 
    CGEventPost(kCGHIDEventTap, click_down); 
    sleep(duration); 
    CGEventPost(kCGHIDEventTap, click_up); 
    sleep(duration); 
    } 

    // Release the events 
    CFRelease(click_down); 
    CFRelease(click_up); 

    return 0; 
} 

Hosted bei https://gist.github.com/Dorian/5ae010cd70f02adf2107

+2

Ich würde 'usleep (Dauer * 1000000)' verwenden. Sonst schlafen Sie nur für eine ganzzahlige Anzahl von Sekunden! – nneonneo

6

Swift Maus bewegen und klicken Beispiel:

func mouseMoveAndClick(onPoint point: CGPoint) { 
    guard let moveEvent = CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: point, mouseButton: .left) else { 
     return 
    } 
    guard let downEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: point, mouseButton: .left) else { 
     return 
    } 
    guard let upEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: point, mouseButton: .left) else { 
     return 
    } 
    moveEvent.post(tap: CGEventTapLocation.cghidEventTap) 
    downEvent.post(tap: CGEventTapLocation.cghidEventTap) 
    upEvent.post(tap: CGEventTapLocation.cghidEventTap) 
}