单击鼠标向下拖动Mac上的对象

时间:2009-11-30 02:47:49

标签: objective-c cocoa macos

我一直在使用以下代码在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);
}

现在,我正在尝试点击向下以便能够拖动对象,例如滚动条或应用程序窗口。我正在使用以下内容:

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

当我运行上面的代码时,会发生一些有趣的事情,当鼠标左键出现问题似乎没有发生时,我移动鼠标并且窗口不移动,但是当我添加鼠标时强>事件然后窗口跳到我认为拖动它的位置。这有点好,但是,如何让鼠标单击并拖动对象呢?

注意:我确实有一个完整的方法来查看鼠标何时停止移动,这样我就可以点击。

请发布代码。 感谢

4 个答案:

答案 0 :(得分:3)

要拖动,必须先按下鼠标按钮,然后移动鼠标。

以编程方式,您应该在kCGEventLeftMouseDraggedkCGEventMouseMoved事件之间发布LeftMouseDown,而不是LeftMouseUp。您可以安装自定义事件点击并记录真实鼠标事件以确认或更正此事件。

答案 1 :(得分:3)

执行所需操作的唯一方法是设置活动CGEventTap以获取可编辑的kCGEventMouseMoved事件流,并将其更改为CGEventTap回调中的kCGEventLeftMouseDragged事件(显然您需要首先合成鼠标按下事件)

你会认为这是通过发送没有释放并移动鼠标的点击事件自动完成的,但事实并非如此。

答案 2 :(得分:2)

虽然在PyObjC中,这确实像宣传的那样有效。但如果你愿意的话,你可以将它反向工程回到Cocoa。

#!/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

答案 3 :(得分:1)

我已经在C:Cocoa中以这种方式重新实现了它:

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

但我遇到了一个一个地执行它的问题。我只在我调用鼠标按下,鼠标拖动和鼠标按钮之间添加一些显着的延迟时工作。

 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