2009-11-30 10 views
5

He estado usando el siguiente código para emitir clics mediante programación en un MacAl hacer clic en el ratón hacia abajo para arrastrar objetos en Mac

void PostMouseEvent(CGMouseButton button, CGEventType type, const CGPoint point) 
{ 
    CGEventRef theEvent = CGEventCreateMouseEvent(NULL, type, point, button); 
    CGEventSetType(theEvent, type); 
    CGEventPost(kCGHIDEventTap, theEvent); 
    CFRelease(theEvent); 
} 

void Click(const CGPoint point) 
{ 
    PostMouseEvent(kCGMouseButtonLeft, kCGEventMouseMoved, point); 
    NSLog(@"Click!"); 
    PostMouseEvent(kCGMouseButtonLeft, kCGEventLeftMouseDown, point); 
    PostMouseEvent(kCGMouseButtonLeft, kCGEventLeftMouseUp, point); 
} 

Ahora, yo estoy tratando de hacer clic abajo para poder arrastrar objetos, como una barra de desplazamiento o la ventana de una aplicación. Estoy usando el siguiente:

PostMouseEvent(kCGMouseButtonLeft, kCGEventMouseMoved, point); 
NSLog(@"Click Down!"); 
PostMouseEvent(kCGMouseButtonLeft, kCGEventLeftMouseDown, point); 

cuando me encontré con el código anterior algo interesante va a pasar, cuando el botón izquierdo del ratón hacia abajo es cuestión nada parece suceder, muevo el ratón y la ventana no se mueve, sin embargo cuando agregué un mouse up evento, la ventana saltó a la ubicación donde supuestamente lo arrastré. esto está algo bien, sin embargo, ¿cómo puedo hacer que el mouse haga clic y arrastrar un objeto?

Nota: Tengo un método completo para ver cuando el mouse deja de moverse para que pueda hacer clic.

por favor, escriba el código. Gracias

Respuesta

3

La única manera de hacer lo que quiere es establecer un CGEventTap activa para conseguir un flujo editable de eventos kCGEventMouseMoved y convertirlos en eventos kCGEventLeftMouseDragged en la devolución de llamada de la CGEventTap (obviamente necesita para sintetizar el evento del ratón en primer lugar)

Podría pensar que esto se hace automáticamente al enviar un evento de clic sin liberación y mover el mouse, pero ese no es el caso.

+1

entonces, ummm, como, ¿cómo lo haces, lol. –

+0

CGEventSetType (event, kCGEventLeftMouseDragged) – valexa

3

Para arrastrar, primero debe presionar el botón del mouse y luego mover el mouse.

Programmatically, probablemente deberías publicar kCGEventLeftMouseDragged, no , entre los eventos LeftMouseDown y LeftMouseUp. Puede instalar un evento personalizado y registrar eventos reales del mouse para confirmar o corregir esto.

+1

sigo sin ver el mismo comportamiento cuando se utiliza kCGEventLeftMouseDragged. ¿Alguna posibilidad de que pueda darme un fragmento? Estoy seguro de que estoy haciendo algo mal. ¡Gracias! – Uri

+1

Bien, intenté crear un evento con CGEventCreateMouseEvent() pero todavía veo el mismo comportamiento ... – Uri

+1

¿Alguien? ¿Nadie tiene una respuesta? – Uri

2

Aunque en PyObjC, esto funciona como se anuncia. Pero puedes revertir la ingeniería a Cocoa si lo deseas.

#!/usr/bin/python 
import sys, time 
from Quartz.CoreGraphics import * 

def mouseEvent(type, posx, posy): 
    theEvent = CGEventCreateMouseEvent(None, type, (posx,posy), kCGMouseButtonLeft) 
    CGEventPost(kCGHIDEventTap, theEvent) 

def mousemove(posx,posy): 
    mouseEvent(kCGEventMouseMoved, posx,posy) 

def mouseclickdn(posx,posy): 
    mouseEvent(kCGEventLeftMouseDown, posx,posy) 

def mouseclickup(posx,posy): 
    mouseEvent(kCGEventLeftMouseUp, posx,posy) 

def mousedrag(posx,posy): 
    mouseEvent(kCGEventLeftMouseDragged, posx,posy) 

ourEvent = CGEventCreate(None) 
currentpos = CGEventGetLocation(ourEvent) # Save current mouse position 

mouseclickdn(60, 100) 
mousedrag(60, 300) 
mouseclickup(60, 300) 

time.sleep(1) 
mousemove(int(currentpos.x), int(currentpos.y)) # Restore mouse position 
1

He reimplementado de esta manera en el cacao en C:

void mouse_left_click_down_at(float x, float y) { 

      /** 
      * create a new Quartz mouse event. 
      * params: 
      * @source : CGEventSourceRef 
      * @mouseType : CGEventType 
      * @mouseCursorPosition : CGPoint 
      * @mouseButton : CGMouseButton 
     */ 
     CGEventRef left_click_down_event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, CGPointMake(x, y), 0); 

     /** 
     * post a Quartz event into the event stream at a specified location. 
     * params: 
     * @tap : CGEventTapLocation 
     * @event : CGEventRef 
     */ 
     CGEventPost(kCGHIDEventTap, left_click_down_event); 

     /** 
     * release a Quartz event 
     */ 
     CFRelease(left_click_down_event); 
    } 
    void mouse_left_click_up_at(float x, float y) { 

     /** 
     * create a new Quartz mouse event. 
     * params: 
     * @source : CGEventSourceRef 
     * @mouseType : CGEventType 
     * @mouseCursorPosition : CGPoint 
     * @mouseButton : CGMouseButton 
     */ 
     CGEventRef left_click_up_event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp, CGPointMake(x, y), 0); 

     /** 
     * post a Quartz event into the event stream at a specified location. 
     * params: 
     * @tap : CGEventTapLocation 
     * @event : CGEventRef 
     */ 
     CGEventPost(kCGHIDEventTap, left_click_up_event); 

     /** 
     * release a Quartz event 
     */ 
     CFRelease(left_click_up_event); 
    } 

    void mouse_left_drag_to(float x, float y) { 

     /** 
     * create a new Quartz mouse event. 
     * params: 
     * @source : CGEventSourceRef 
     * @mouseType : CGEventType 
     * @mouseCursorPosition : CGPoint 
     * @mouseButton : CGMouseButton 
     */ 
     CGEventRef left_drag_event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDragged, CGPointMake(x, y), 0); 

     /** 
     * post a Quartz event into the event stream at a specified location. 
     * params: 
     * @tap : CGEventTapLocation 
     * @event : CGEventRef 
     */ 
     CGEventPost(kCGHIDEventTap, left_drag_event); 

     /** 
     * release a Quartz event 
     */ 
     CFRelease(left_drag_event); 
    } 

Pero me encuentro con algún problema con la ejecución de uno por uno. Solo funciona cuando agrego un retraso significativo entre la invocación del mouse hacia abajo, el arrastre del mouse y el mouse hacia arriba.

mouse_left_click_at(400.0, 200.0);   // get focus 
    usleep(10000); 

    mouse_left_click_down_at(400.0, 200.0);  // start dragging 
    usleep(10000); 
    mouse_left_drag_to(500.0, 400.0);   // continue dragging 
    usleep(10000); 
    mouse_left_drag_to(600.0, 500.0); 
    usleep(10000); 
    mouse_left_drag_to(700.0, 600.0); 
    usleep(10000); 
    mouse_left_drag_to(800.0, 700.0); 
    usleep(10000); 
    mouse_left_click_up_at(800.0, 700.0);  // stop dragging 
Cuestiones relacionadas