Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 如何以编程方式模拟鼠标单击而不在Cocoa中移动鼠标_Macos_Cocoa_Accessibility_Macos Carbon - Fatal编程技术网

Macos 如何以编程方式模拟鼠标单击而不在Cocoa中移动鼠标

Macos 如何以编程方式模拟鼠标单击而不在Cocoa中移动鼠标,macos,cocoa,accessibility,macos-carbon,Macos,Cocoa,Accessibility,Macos Carbon,我感兴趣的是在Mac OS X上模拟鼠标点击事件/键盘笔划,而不实际移动鼠标 在Windows中,可以使用以下消息执行此操作: Mac OS X有类似的功能吗?我知道,但API似乎只会限制我将事件发送到当前密钥窗口。这是真的吗?是否可以将键盘/鼠标事件发送到非按键窗口?我真的只需要能够将键盘命令发送到另一个应用程序。我知道这是一个旧线程,但我想发布一个答案,以防有人无意中发现 实现这一点的两种最佳方法实际上是完全独立于平台的。(除非您想使用C,在我看来这是不必要的冗长,但如果您想使用它) 1)

我感兴趣的是在Mac OS X上模拟鼠标点击事件/键盘笔划,而不实际移动鼠标

在Windows中,可以使用以下消息执行此操作:


Mac OS X有类似的功能吗?我知道,但API似乎只会限制我将事件发送到当前密钥窗口。这是真的吗?是否可以将键盘/鼠标事件发送到非按键窗口?我真的只需要能够将键盘命令发送到另一个应用程序。

我知道这是一个旧线程,但我想发布一个答案,以防有人无意中发现

实现这一点的两种最佳方法实际上是完全独立于平台的。(除非您想使用C,在我看来这是不必要的冗长,但如果您想使用它)

1)最简单的方法是使用。(注意:javAuto已经移动)。它几乎是一个java程序,可以跨平台编译和运行基本的自动化脚本。要模拟鼠标单击,可以使用以下命令:

mouseClick(按钮,x,y)

要在不移动鼠标的情况下模拟鼠标单击,可以使用以下方法:

// get cursor coordinates
int cPos[] = cursorGetPos();

// mouse click at the coordinates you want
mouseClick("left", x, y);

// instantly move the mouse back
mouseMove(cPos[0], cPos[1]);
由于mouseClick和mouseMove命令不涉及任何临时鼠标移动,因此会在(x,y)处单击鼠标,但鼠标根本不会移动

2)实现这一点的下一个最好的方法是使用常规Java,这将比javAuto中的相同过程涉及更多的代码

import java.awt.*;
import java.awt.event.InputEvent;

public class example {
    public static void main(String[] args) {
        //get the current coordinates
        PointerInfo a = MouseInfo.getPointerInfo();
        Point b  = a.getLocation();
        int xOrig = (int)b.getX();
        int yOrig = (int)b.getY();

        try {
            //simulate a click at 10, 50
            Robot r = new Robot();
            r.mouseMove(10, 50);
            r.mousePress(InputEvent.BUTTON1_MASK); //press the left mouse button
            r.mouseRelease(InputEvent.BUTTON1_MASK); //release the left mouse button

            //move the mouse back to the original position
            r.mouseMove(xOrig, yOrig);
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}

您可以使用NSEvent、CGEvent或辅助功能API来实现这一点。诀窍是,如果应用程序不是最前面的应用程序,通常首先需要使您想要的应用程序单击activate first。然后,您只需单击屏幕坐标中的一个点。

下面是一个正在运行的C程序,用于模拟在坐标(X,Y)处的N次单击:

//编译指令:
//
//gcc-o click.c-Wall-framework应用程序服务

#include

可能重复的I可能是错误的,但我相信您的问题主要是应用程序本身选择哪个窗口响应事件。换句话说,不会有任何操作系统级API来实现这一点。我建议尝试通过AppleScript和System Events suite来实现这一点,如果可以这样做,那么就可以通过编程实现。否则,这可能是相当困难的。看看CGEventPostTopsI,我不再从事这个项目了,但说真的,伟大的发现者!我相信这将在将来帮助很多其他人:)@John你知道如何使用javAuto来确定是否执行了单击吗?另外,javAuto可以导入吗?@它肯定可以导入类型列表,但是我几乎可以肯定,根本无法检测单击是否在java中执行,因为它在JVM上运行,并且没有连接到操作系统。我认为检测鼠标点击是你想用C来实现的,并且必须依赖于平台。那些JavAuto链接被破坏了。现在在这里:
// 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;
}