2010-04-29 16 views
52

È possibile simulare le azioni di un mouse da un programma in OS X? In particolare, la versione breve è che sto cercando di simulare un touchscreen utilizzando due webcam. Quindi, assumendo che io possa ottenere posizioni X, Y, posso inviare informazioni al SO come movimento del mouse o fare clic?Simulazione dell'input del mouse in modo programmatico in OS X

Modifica - O se è particolarmente facile in un altro sistema operativo, sarei disposto a prenderlo in considerazione.

+0

A seconda del caso d'uso, c'è un Strumento chiamato "UI Recorder" che registra tutto ciò che fai all'interfaccia utente del tuo programma e lo riproduce quando vuoi. – zneak

+0

Grazie, ma quello che voglio veramente è inviare qualsiasi input del mouse arbitrario al sistema operativo. –

+3

L'ho fatto prima eseguendo un server di vnc e scrivendo un piccolo client di vnc per inviare gli eventi del mouse al server. Ci sono server di vnc open source che lo fanno, quindi una buona ultima risorsa sarebbe quella di leggere la fonte di uno. –

risposta

82

Sì, è possibile. È possibile utilizzare Quartz Event Services per simulare eventi di input.

Supponendo C, ho scritto questo rapido esempio:

#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; 
} 

e assumendo GCC, compilare con:

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

godersi la magia.

+2

Whoa, ottima risposta a una vecchia domanda, grazie! –

+0

@Rob: prego. Spero che la risposta non sia arrivata troppo tardi. – jweyrich

+0

funziona come un fascino – piaChai

7

Se non si desidera compilare le cose e si sta cercando uno strumento basato su shell, la soluzione potrebbe essere la Cliclick.

2

Ecco un programma di lavoro C in base alla risposta del jweyrick:

// 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; 
} 

ospitata presso https://gist.github.com/Dorian/5ae010cd70f02adf2107

+2

Vorrei usare 'usleep (duration * 1000000)'. Altrimenti dormirai solo per un numero intero di secondi! – nneonneo

6

Swift movimento del mouse e fare clic su esempio:

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) 
} 
Problemi correlati