【问题标题】:Clicking the mouse down to drag objects on Mac在 Mac 上单击鼠标向下拖动对象
【发布时间】:2009-11-30 02:47:48
【问题描述】:

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

当我运行上面的代码时会发生一些有趣的事情,当鼠标左键按下时似乎什么都没有发生,我移动鼠标并且窗口没有移动,但是当我添加鼠标时 up 事件然后窗口跳到我应该拖动它的位置。这有点好,但是,我怎样才能让鼠标点击并拖动一个对象?

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

请张贴代码。 谢谢

【问题讨论】:

    标签: objective-c cocoa macos


    【解决方案1】:

    做你想做的唯一方法是设置一个活动的 CGEventTap 来获取一个可编辑的 kCGEventMouseMoved 事件流,并在 CGEventTap 的回调中将它们更改为 kCGEventLeftMouseDragged 事件(显然你需要先合成鼠标按下事件)

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

    【讨论】:

    • CGEventSetType(event,kCGEventLeftMouseDragged)
    【解决方案2】:

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

    以编程方式,您可能应该在LeftMouseDownLeftMouseUp 事件之间发布kCGEventLeftMouseDragged,而不是kCGEventMouseMoved。您可以安装自定义事件点击并记录真实的鼠标事件以确认或更正这一点。

    【讨论】:

    • 我在使用 kCGEventLeftMouseDragged 时仍然看到相同的行为。你有机会给我一个sn-p吗?我确定我做错了什么。谢谢!
    • 好的,我尝试使用 CGEventCreateMouseEvent() 创建一个事件,但我仍然看到相同的行为...
    • 有人吗?没人知道答案吗?
    • Uri,你有答案吗?我确实遵循“鼠标左下”“鼠标左拖动”“鼠标左上”,但“鼠标左上”似乎不起作用。拖动事件似乎没有办法摆脱。
    【解决方案3】:

    虽然在 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
    

    【讨论】:

    • 这个脚本对其他人有用吗?我注意到它移动了鼠标,但在拖动时它没有选择任何东西。
    【解决方案4】:

    我已经在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 2021-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多